CORS 真的让我发疯,我真的没有想法让它变得有用。
我创建了一个名为'abc'的简单APIG Api,并添加了2个方法 GET 和 POST ,并且授权设置为 NONE 和 API Key Required 设置为 false ,所有内容都部署到名为“dev”的阶段。
当然我在两种方法上都启用了 CORS ,我看到3个标题 Access-Control-Allow-Origin , Access-Control-Allow-Headers < / strong>和 Access-Control-Allow-Methods 添加到 OPTIONS 方法,并且 Access-Control-Allow-Origin 添加到< em> POST 和 GET 方法。
两个调用都映射到相同的 lambda 函数,该函数只是将“Hello from Lambda”文本输出到控制台。
然后我在 S3 上创建了一个我作为静态网站托管的简单html页面,使用 Route53 指向了一个域并启动了它使用 jQuery $ .ajax 测试API以进行调用。
一切看似简单,直截了当,完全如文档中所述,只有 GET 工作并按预期将文本输出到控制台。 POST 版本会导致以下错误:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://example.com' is therefore not allowed access. The response had HTTP status code 400.
预检调用工作并返回200 OK并且所有标题都在那里,但POST调用返回该错误和400 Bad Request。
请非常感谢任何帮助,我希望AWS团队也在关注......
谢谢你们。
已编辑 - 从Google Chrome复制:
POST Raw Request Headers:
POST /dev/urls HTTP/1.1
Host: kykul1mshe.execute-api.us-east-1.amazonaws.com
Connection: keep-alive
Content-Length: 73
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
Content-Type: application/json
Referer: http://example.com/dev.html
Accept-Encoding: gzip, deflate, br
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
POST Raw Response Headers:
HTTP/1.1 400 Bad Request
Date: Fri, 19 Aug 2016 02:14:16 GMT
Content-Type: application/json
Content-Length: 177
Connection: keep-alive
x-amzn-RequestId: a1160e45-65b2-11e6-9766-cd61e49fbcdb
X-Cache: Error from cloudfront
Via: 1.1 d64756b4df47ce24d6c62b5a8de97e87.cloudfront.net (CloudFront)
X-Amz-Cf-Id: N9mf7apicKbSM_MiZjePbEgZGIFKckWJ3lZljH8iHVKFVTcIIOQuHg==
这将返回400 Bad Request
选项原始请求标题:
Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Access-Control-Request-Headers:accept, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:kykul1mshe.execute-api.us-east-1.amazonaws.com
Origin:http://example.com
Referer:http://example.com/dev.html
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
选项原始响应标题:
Access-Control-Allow-Headers:Content-Type,X-Amz-Date,Authorization,X-Api-Key,Cache-Control,X-Requested-With
Access-Control-Allow-Methods:POST,OPTIONS
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Length:79
Content-Type:application/json
Date:Fri, 19 Aug 2016 02:14:16 GMT
Via:1.1 d64756b4df47ce24d6c62b5a8de97e87.cloudfront.net (CloudFront)
X-Amz-Cf-Id:KpGEDmIuf5RHcUnBWuA3oEMZgWHwrjy3SpLuOflRhAD8IIx5vyKGSw==
x-amzn-RequestId:a10bae11-65b2-11e6-bcf7-63b49c24629e
X-Cache:Miss from cloudfront
返回200 OK
答案 0 :(得分:17)
好的,我发现问题的根源,恰好与APIG完全无关,并确认了@AbhignaNagaraja提到的,我的APIG配置正确。
这个问题实际上就是我调用jQuery.ajax的方式,我认为它足够智能,当contentType是&#39; application / json&#39;时,我的参数转换为JSON字符串。 看来我必须手动字符串化JSON参数而不是传递JSON并让jQuery对其进行字符串化。
所以这是不好的电话:
$.ajax({
url: myEndpoint,
type: 'POST',
crossDomain: true,
data: {
url: $('#url').val()
},
headers: {
"X-Api-Key": 'blablabla'
},
dataType: 'json',
contentType: "application/json",
success: function (data) {
console.info(data);
}
});
这是正确的电话:
$.ajax({
url: myEndpoint,
type: 'POST',
crossDomain: true,
data: JSON.stringify({
url: $('#url').val()
}),
headers: {
"X-Api-Key": 'blablabla'
},
dataType: 'json',
contentType: "application/json",
success: function (data) {
console.info(data);
}
});
如果您正在使用CORS调试此类问题,这可能是一个提示:只需下载AWS APIG SDK并尝试使用AWS提供的apigClient执行调用,并将标头与您在自定义客户端上获得的标头进行比较。 在检查我使用 jQuery 和 apigClient 获得的两组标头时,我注意到Request Payload看起来不同,这就是我如何意识到格式错误,然后 400代码和 No&#39; Access-Control-Allow-Origin&#39; 标题都是有意义的。
我希望这会有所帮助。
答案 1 :(得分:12)
我有类似的问题,但使用lambda代理集成:
使用浏览器在AWS API Gateway上激活CORS
激活lambda-proxy集成
使用lambda代理集成时,您可以从lambda代码中返回自定义标头:
var result = {
statusCode: data.statusCode | 200,
headers: {
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify(responseBody)
};
callback(null, result);
这样您就可以获得CORS标头了。 我认为有一种更好的方法可以让它与lambda代理集成一起工作,而不需要在lambda的代码中耦合CORS,如果你知道的话请告诉我。
答案 2 :(得分:3)
我遇到了类似的问题 - 它与配置API的方式或我在前端发出的POST请求无关。解决这个问题的原因是在AWS API Gateway上部署API。一旦创建了API方法/资源,并将它们绑定到lambda函数,它们就不会自动部署。
您必须单击“操作”,然后单击“部署API”才能从前端访问这些MicroServices。
答案 3 :(得分:3)
如果您在API Gateway中使用代理集成,则无法从API Gateway启用CORS。您必须从Lambda代码本身设置标头“ Access-Control-Allow-Origin”。
它在doc中提到。
Python代码示例:
response = {
'statusCode': 200,
'headers': {
'Access-Control-Allow-Origin': '*'
},
'body': json.dumps({'message': 'CORS enabled')
}
return response
答案 4 :(得分:2)
解决此问题,我将在apy网关中提供Post配置的配置
选项方法 - 集成REsponse - 标题映射
X-Requested-With '*'
Access-Control-Allow-Headers 'Content-Type,x-requested-with,Access-Control-Allow-Origin,Access-Control-Allow-Headers,Access-Control-Allow-Methods'
Access-Control-Allow-Origin 'http://localhost:4200'
Access-Control-Allow-Methods 'POST,OPTIONS'
发布方法 - 集成响应 - 标题映射
Access-Control-Allow-Origin "*" ---> can be changed by your ip obviously
我希望这有助于你
答案 5 :(得分:0)
有很多帖子指导您确保lambda函数返回相应的CORS标头并且它们是正确的。但是,使用JSON.stringify()对json对象进行字符串化也是 critical 。似乎Postman为我们做了这个,所以当Postman请求和$ .ajax请求发送相同的json对象时它会产生误导;但是一个成功,一个失败。
答案 6 :(得分:0)
我也陷于此错误中,在挖掘之后,我发现在非2XX
响应中,API没有在响应中提供Access-Control-Allow-Origin
标头。因此,尽管OPTION
方法和成功的(2XX
)响应都具有此标头,但4XX
和5XX
没有。也可以使用PostMan并检查不良响应的标头来确认这一点。
调整配置后,我确保在所有响应中都返回该标头。
答案 7 :(得分:0)
如果lambda超时很小,有时会发生CORS错误。
答案 8 :(得分:0)
到2020年,API网关CORS问题仍在寻找其他原因。对我来说(不使用lambda代理),即使在使用API下拉菜单启用CORS之后,甚至在我的Lambda函数的响应中添加了“ Access-Control-Allow-Origin”标头之后,我仍然收到CORS错误。>
在默认网关响应中添加“ Access-Control-Allow-Origin”后,它为我解决了什么。在API网关用户界面的左侧菜单中,找到网关响应。选择“默认4XX”并对其进行编辑以包含“访问控制允许来源”。我将'*'的值设置为在测试期间完全开放(包括引号)。对“默认5XX”执行相同的操作。我的ajax调用能够传递CORS错误,现在我看到了真正的原因-我为该方法设置的必需参数未正确传递。
但是,我不知道为什么会出现CORS错误。