触发 API 网关端点时 COR 配置错误
Posted
技术标签:
【中文标题】触发 API 网关端点时 COR 配置错误【英文标题】:CORs misconfigured while triggering API Gateway endpoint 【发布时间】:2020-01-05 03:21:48 【问题描述】:我正在尝试使用 AJAX 从我的网站触发 AWS API Gateway 上的 API。我的 API Gateway 触发了 Lambda。我在 S3 上托管了我的网站。
我的 AJAX 代码如下所示:
$.ajax(
type: "POST",
url: api-gateway-api-endpoint-goes-here,
data: str,
dataType: 'json',
contentType: 'application/json',
crossDomain: true,
headers:
'Access-Control-Allow-Origin': "*",
'Access-Control-Allow-Credentials': 'true',
'Access-Control-Allow-Methods': 'OPTIONS,POST',
'Access-Control-Allow-Headers': 'access-control-allow-origin'
,
success: function(msg)
// blah blah
);
lambda 处理程序看起来有点像这样:
def lambda_handler(event, context):
# call SES send-email API
aws_ses_response = ses_client.send_email(
Source=blah,
Destination=blah,
Message=blah
)
return
'response': aws_ses_response
我已经在 API Gateway 上的 API 端点上“启用”了 CORS。我将access-control-allow-origin
添加为Integration Response
中Access-Control-Allow-Headers
映射中的值之一。
触发此 AJAX 调用时,我仍然看到此错误:
Access to XMLHttpRequest at 'https://xxxxxxx.execute-api.xxxxx.amazonaws.com/dev/my-api' from origin 'http://www.my-website.com' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.
当我从终端从 cURL 触发 API 时,它工作正常。
我错过了什么?谢谢。
附:我在这里查看了一些类似的问题,但没有一个建议有效。所以,再次在这里发布。
--
更新:在遵循@hephalump 的建议后,我能够触发我的 API,只是 API 响应似乎没有传播回网站(托管在 S3 上)。我在发送 AJAX POST 请求后“检查”我的网站时看到此错误:
【问题讨论】:
您的 API 是否触发了 Lambda? @hephalump - 是的 你能发布你的 Lambda 代码吗? @hephalump - 我刚刚用 lambda 代码更新了我的问题。基本上我正在调用 AWS SES api 并从我的 lambda 返回来自该 API 的响应。 昨晚我从字面上回答了同样的问题,显然是同样的问题,而 OP 似乎已经删除了它。我会再写回复。 【参考方案1】:查看错误信息:
请求头域 access-control-allow-origin 不允许
现在看看你的请求:
headers: 'Access-Control-Allow-Origin': "*", 'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Methods': 'OPTIONS,POST', 'Access-Control-Allow-Headers': 'access-control-allow-origin' ,
您正在尝试为您的请求设置权限。
如果您的 javascript 可以允许自己访问它喜欢的任何服务,那将是完全愚蠢的。这意味着这些标题是废话。
由于它们是无稽之谈,它们不在跨域请求的可接受标头列表中,因此服务器需要明确授予您设置它们的权限……但它没有。
停止尝试设置它们。
Access-Control-*
标头需要由服务器设置。
请参阅Amazon's own documentation,其中明确涵盖了这一点。
【讨论】:
【参考方案2】:当使用启用了 API 网关和 CORS 的 Lambda 代理集成时,您的浏览器会期望在响应中返回 CORS 标头。目前,您正在返回 ses_client.send_email 的结果,如果它只是原始 SES sendEmail 原始响应,它将类似于:
"ResponseMetadata":
"RequestId": "99aaaaa9-a9aa-9999-aa99-744d6b6ede3c"
,
"MessageId": "0100000aa0a00a0a-715e3e9e-e010-43c1-a91f-0492d75aa64c-000000"
正如我们所见,这不包括浏览器所需的 CORS 标头。要解决此问题,首先构建 aws_ses_response
的结果以包含 HTTP 状态代码和相应的标头,然后将完整的响应返回给调用者。修改您的代码如下,它应该可以工作:
aws_ses_response = ses_client.send_email(
Source=blah,
Destination=blah,
Message=blah
)
const result =
statusCode: 200,
headers:
'Access-Control-Allow-Origin': '*',
// other required headers
,
body: aws_ses_response
;
return result;
此外,尽管您的 API 网关的配置对我来说并不完全清楚,但对于您的请求,您可以删除标头和跨域属性(可能还有其他属性)。在新的 APIG 端点上对此进行测试时,我只是在没有这些的情况下向 API 发出请求,并且能够获得成功的响应(我的响应主体是我为原始 SES sendEmail 响应提供的示例)。
【讨论】:
现在我可以调用我的 lambda 函数并且可以发送电子邮件了。 (是的!)。但是,我无法回复我的网站(托管在 S3 上)。我在响应中看到此错误: 从源“MY-SITE”访问“MY-APIG-ENDPOINT”处的 XMLHttpRequest 已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头.跨域读取阻塞 (CORB) 阻止了 MIME 类型为 application/json 的跨域响应 My-APIG-ENDPOINT。有关详细信息,请参阅chromestatus.com/feature/5629709824032768。 刚刚贴在上面的回复里。 您是否从请求中删除了标头? 是的,我从 ajax 请求中删除了标头和“crossDomain”。API 调用得很好。只是我的网站无法得到响应。谢谢。以上是关于触发 API 网关端点时 COR 配置错误的主要内容,如果未能解决你的问题,请参考以下文章
对 Kong api 网关端点的基本身份验证请求出现 CORS 错误并且未找到预检
我无法创建网关 API Google 错误:“无法转换为服务配置。”位置:“未知位置”