API Gateway对接Lambda GET报CORS缺失Allow-Origin头POST正常
更新说明
- EDIT2:GET请求不会发送JSON数据是本次遇到的核心问题,目前正尝试将数据改为URL参数传递,当前帖子无法删除。
- EDIT:通过开发者工具网络面板排查确认,问题并非出在预检(preflight)请求:POST请求可正常携带JSON数据,但GET请求无法携带JSON数据;此前Lambda尝试读取请求中的JSON数据时发生崩溃,导致响应缺失Origin头,添加try/except块捕获该异常后,仍未定位GET请求不发送数据的原因。
问题描述
浏览器抛出跨域报错:No 'Access-Control-Allow-Origin' header is present on the requested resource。
后端为部署在AWS REST API Gateway上的AWS Lambda函数,POST请求可正常访问,GET请求触发如下跨域错误:
Access to XMLHttpRequest at 'https://my_url.amazonaws.com/dev/quark/customers' from origin 'http://localhost:8081' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
- GET与POST请求的配置完全一致,CloudWatch日志显示响应中已正确配置所有CORS相关响应头。
- 以下两个curl命令均可正常执行得到预期响应,但浏览器端通过JS发起请求时,仅POST请求可正常运行:
curl -X POST -H 'Authorization: Basic API_AUTH_KEY' -H "Cache-Control: no-cache" https://my_url.amazonaws.com/dev/quark/customers -d @./data_for_testing/customer.json curl -X GET -H 'Authorization: Basic API_AUTH_KEY' -H "Cache-Control: no-cache" https://my_url.amazonaws.com/dev/quark/customers -d @./data_for_testing/customer.json
- 目前已临时关闭Authorization校验,待CORS问题修复后再重新开启。
- 分别在Chrome、Firefox浏览器测试,问题复现现象完全一致。
- 开发阶段已将
Access-Control-Allow-Origin设置为请求头携带的Origin值,即使将该值配置为通配符*也无法解决问题。 - 经查阅资料确认,不带Authorization头的GET请求本不需要触发预检请求,但实际发起GET调用时仍然被跨域策略拦截。
后端Lambda函数代码
import logging def lambda_handler(event, context): logging.getLogger().setLevel(logging.INFO) logging.info(event["headers"]["Origin"]) response = { 'statusCode': 200, 'headers': { 'Access-Control-Allow-Headers': 'Content-Type, Authorization', 'Access-Control-Allow-Credentials': True, 'Access-Control-Allow-Origin': event["headers"]["Origin"], 'Access-Control-Allow-Methods': 'POST,GET,DELETE,PATCH' }, 'isBase64Encoded':False, 'body': "" } logging.info(response) return response
前端请求代码
function send() { var ItemJSON; ItemJSON = '{ "customer_info": { "customer_shortname":"WU2", "deploy_pending": "ams,arn,dal,fra,gru,iad,lax,lcy,lga,nrt,sin,sjc,syd" }, "object_type":"customer"}'; URL = "https://my_url.amazonaws.com/dev/quark/customers" var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = callbackFunction(xmlhttp); xmlhttp.open("GET", URL, false); xmlhttp.setRequestHeader("Content-Type", "application/json"); //xmlhttp.setRequestHeader('Authorization', 'Basic API_AUTH_KEY'); //生产环境需加密用户名密码,传入加密后的密钥 xmlhttp.onreadystatechange = callbackFunction(xmlhttp); xmlhttp.send(ItemJSON); alert(xmlhttp.responseText); document.getElementById("div").innerHTML = xmlhttp.statusText + ":" + xmlhttp.status + "<BR><textarea rows='100' cols='100'>" + xmlhttp.responseText + "</textarea>"; } function callbackFunction(xmlhttp) { //alert(xmlhttp.responseXML); }
</script> <html> <body id='bod'><button type="submit" onclick="javascript:send()">call</button> <div id='div'> </div></body> </html>
排查截图

内容的提问来源于stack exchange,提问作者J Kast
相关产品推荐
相关产品推荐

