amazon-web-services - 尽管设置了标头,但调用 API 网关返回 CORS 错误
问题描述
我有一个与 Lambda 函数集成的 API 网关(HTTP 类型)。我正在尝试从 localhost 调用该函数,如下所示:
const jwt = getAuthToken();
const formBody = new FormData();
formBody.set('user', 'test');
const res = await fetch('https://example.execute-api.eu-west-1.amazonaws.com/default/GetShareValue', {
method: 'POST',
body: formBody,
headers: {
'Authorization': jwt
}
});
但是,我收到此错误消息:
CORS 策略已阻止从源“http://localhost:3000”访问“https://example.execute-api.eu-west-1.amazonaws.com/default/GetShareValue”获取:响应预检请求未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。
我了解不正确的 CORS 设置会阻止浏览器显示 Lambda 函数返回的内容。但是,我的 API Gateway 指定了 CORS 设置:
根据这个线程,在 Lambda 函数的响应中设置标头很重要。我已将它们设置为相同。这是我的 Lambda 函数:
exports.handler = async (event, context) => {
let body;
let statusCode = '200';
const headers = {
'Content-Type': 'application/json',
"Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,X-Amz-Security-Token,Authorization,X-Api-Key,X-Requested-With,Accept,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Access-Control-Allow-Headers",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "*",
"X-Requested-With": "*"
};
try {
body = "Success!!";
} catch (err) {
statusCode = '400';
body = err.message;
} finally {
body = JSON.stringify(body);
}
return {
statusCode,
body,
headers,
};
};
我可以在 Postman 中调用这个端点——它不关心 CORS——所以我知道它正在工作。我开始认为这是 AWS 本身的一个错误。
解决方案
为了@peter n 的利益回答我自己的问题。
最后我放弃了 HTTP API 网关。我相信 AWS 中存在一个错误,因为当我通过 REST API 触发它时,完全相同的 Lambda 函数起作用了。这就是我所做的。
- 创建新的 API 网关
- 选择 API Gateway 的类型为REST API。我之前选择了 HTTP。REST API 给了我们更多的控制权;HTTP API 很简单(而且便宜 70%)
- 在资源页面上,单击操作 > 创建资源
- 创建资源;如果您看到任何提到 CORS 的复选框,请检查它。我不记得这是否发生在这个阶段。
- 然后单击操作 > 创建方法
- 选择“任何”以外的任何方法(如 POST、GET 等)。这很重要 - 如果您选择“任何”,CORS 会出现更多问题。为什么?谁知道,AWS 是一个用户不友好的平台。
- 一旦您配置了该方法并让它在您的 Lambda 函数(或您正在集成的任何东西)上触发,就可以使用 Postman 之类的东西来测试它,它不关心 CORS。
- 最后,要让 CORS 正常工作,请单击 Actions > Enable CORS
我输入了以下设置:
方法:POST
访问控制允许方法:选项,POST
Access-Control-Allow-Headers : 'Content-Type,X-Amz-Date,X-Amz-Security-Token,Authorization,X-Api-Key,X-Requested-With,Accept,Access-Control-Allow-Methods ,Access-Control-Allow-Origin,Access-Control-Allow-Headers'
访问控制允许来源:'*'
然后单击“启用 CORS 并替换现有的 CORS 标头”。
你还没有完成。如果您以 Lambda 函数为目标,这仍然无法解决问题。您需要将 CORS 标头添加到 Lambda 的实际响应中。
这是我的 Lambda 的完整代码:
exports.handler = async (event, context) => {
let body = JSON.stringify('Success!');
let statusCode = '200';
const headers = {
'Content-Type': 'application/json',
"Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,X-Amz-Security-Token,Authorization,X-Api-Key,X-Requested-With,Accept,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Access-Control-Allow-Headers",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "*",
"X-Requested-With": "*"
};
return {
statusCode,
body,
headers,
};
};
我不确定您在 Lambda 中返回的 CORS 设置是否与您在 AWS 控制台中应用的 CORS 设置相同。
这是一个真正令人头疼的问题,除非我做错了什么,否则 AWS 实施得非常糟糕。
更新:在遇到进一步的问题后,我想我会更新我的答案,说明您提出的请求似乎也会影响 CORS。我正在更改我的 API 并且 CORS 错误再次开始发生;最终,唯一的解决方案是删除我发送给 AWS 的请求中的一些标头。
这导致了 CORS 错误:
const res = await fetch('https://123.execute-api.eu-west-1.amazonaws.com/test', {
method: 'POST',
headers: {
'Authorization': jwt,
"Access-Control-Allow-Origin": "*" // This had to be removed to fix the CORS error
}
});
如您所见,我Access-Control-Allow-Origin
在对我的 API 的出站请求中进行了指定。这一直存在并且从未引起问题,但似乎现在我可以在请求中评论和取消评论该行并获取/不获取 CORS 错误。
更新#2:进一步的更新可以拯救任何可能为此撞墙的人。在向现有 API 网关添加新的源和方法后,请务必单击Actions > Deploy API
以使您的更改真正生效。
AWS 确实需要清理 API Gateway 和 Lambda 的整个 UI。根本不清楚您是否有未发布的更改,或者甚至需要发布;用户界面使任何更改看起来都立即生效。
推荐阅读
- air - 将 Adobe Flex Web 应用程序迁移到 Adobe AIR 包应用程序 - ExternalInterface.call 失败
- kotlin - 将 json 模式动态转换为 kotlin 数据类
- php - php购物车,堆栈数量
- python-3.x - 在 Python3 asyncio 中与子进程通信
- networking - 为 ARK 服务器转发多个路由器的端口
- sql-server - 使用 convert 函数时将 varchar 转换为 int 时出错
- javascript - 连接到不同主机上的多个 SignalR 集线器
- angular - 如何将工具提示添加到正式字段
- javascript - 是否可以运行无限循环而不阻塞执行流程?
- java - 如何使用 SocketTImeoutException 模拟 Socket 以进行 JUnit 测试?