我有一个与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
}
});
但是,我收到此错误消息:
访问地址为 'https://example.execute-api.eu-west-1.amazonaws.com/default/GetShareValue' 来自来源“ http:// localhost:3000”的信息已被CORS策略阻止: 对预检请求的响应未通过访问控制检查:否 请求中出现“ Access-Control-Allow-Origin”标头 资源。如果不透明的响应满足您的需求,请设置请求的 模式设置为“ no-cors”,以在禁用CORS的情况下获取资源。
我知道错误的CORS设置会阻止浏览器显示Lambda函数返回的内容。但是,我的API网关指定了CORS设置:
According to this thread,在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本身的错误。
答案 0 :(得分:3)
为@peter n的利益回答我自己的问题。
最后,我放弃了HTTP API网关。我相信AWS中存在一个错误,因为当我通过REST API触发该Lambda函数时,它确实发挥了作用。这就是我所做的。
我输入了以下设置:
方法:POST
访问控制权限方法:选项,发布
访问控制允许标题:“内容类型,X-Amz-日期,X-Amz-安全令牌,授权,X-Api密钥,X-Requested-With ,接受,允许访问控制的方法,允许访问控制的起源,允许访问控制的标题的
访问控制允许来源:“ *”
然后单击“启用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
}
});
如您所见,我在我的API的出站请求中指定了Access-Control-Allow-Origin
。它始终存在,并且从未引起问题,但是现在看来,我可以在请求中注释和取消注释该行,并获取/不获取CORS错误。
更新#2::进一步的更新是为了保存可能为此撞墙的任何人。在向现有的API网关添加新的来源和方法后,请确保点击{ {1}},使您的更改真正生效。
AWS确实需要清理API网关和Lambda的整个UI。尚不清楚您尚未发布更改,甚至还不需要发布;用户界面使所有更改都立即生效。
答案 1 :(得分:1)
主要问题在于Options方法提供的答案。出于某种原因,模拟响应(至少在我的情况下)无法正常工作,因此我将其与 lambda 相关联,其唯一目的是使用 200 代码进行响应并返回所有必要的标头。
因此,您需要做的是,在启用了 CORS 的资源的 options 方法中,将集成请求更改为 Lambda。
一旦完成,我们必须开发 lambda,使其返回 200 作为响应并接受所有必要的标头:
{
'statusCode': 200,
'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": "*"
},
'body': json.dumps({})
}