jQuery AWS API 网关不存在“Access-Control-Allow-Origin”标头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40832288/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AWS API Gateway No 'Access-Control-Allow-Origin' header is present
提问by user12345
I'm stuck on an issue with API gateway and I've gone through all the other SO answers on this, AWS forums and have been through their docs but still no joy.
我遇到了 API 网关的问题,我已经浏览了所有其他关于此的 SO 答案、AWS 论坛并浏览了他们的文档,但仍然没有任何乐趣。
I am trying to setup an API using AWS API gateway which calls a Lambda function which reads/writes to a table in DynamoDB.
我正在尝试使用 AWS API 网关设置 API,该网关调用 Lambda 函数,该函数读取/写入 DynamoDB 中的表。
The Lambda function to DynamoDB is working. I have created an API in AWS, and created a GET and OPTIONS methods for it. I read AWS does not enforce the OPTIONS for only GET/POST but i was getting a preflight error in my ajax call when there was no OPTIONS method so I added one.
DynamoDB 的 Lambda 函数正在运行。我在 AWS 中创建了一个 API,并为它创建了一个 GET 和 OPTIONS 方法。我读到 AWS 不只对 GET/POST 强制执行 OPTIONS,但是当没有 OPTIONS 方法时,我在 ajax 调用中遇到了一个预检错误,所以我添加了一个。
For now just to make progress I am not using an API key or Authorization. I can successfully call my GET method using POSTMAN, which returns the contents of the DynamoDB table.
现在只是为了取得进展,我没有使用 API 密钥或授权。我可以使用 POSTMAN 成功调用我的 GET 方法,该方法返回 DynamoDB 表的内容。
But when i try using a JQuery ajax call i get
但是当我尝试使用 JQuery ajax 调用时,我得到
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
I can see using Chrome dev tools under the network tab, the OPTIONS method returning status 200 and the GET returns status 200 but with the above error.
我可以看到在网络选项卡下使用 Chrome 开发工具,OPTIONS 方法返回状态 200,GET 返回状态 200,但出现上述错误。
I have tried enabling CORS on both the OPTIONS and GET methods, have re-deployed the API after every change, have tried the following (http://enable-cors.org/server_awsapigateway.html) but always get the same error in the console.
我尝试在 OPTIONS 和 GET 方法上启用 CORS,在每次更改后重新部署 API,尝试了以下(http://enable-cors.org/server_awsapigateway.html)但总是在安慰。
I am executing the ajax call from a file on my desktop so origin is null as the page will be deployed to S3 as its a single web page application in JS.
我正在从桌面上的文件执行 ajax 调用,因此 origin 为空,因为该页面将作为 JS 中的单个网页应用程序部署到 S3。
When I enabled CORS on my GET and OPTIONS i can see that Access-Control-Allow-Headers is 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'
and Access-Control-Allow-Origin* is '*'
当我在 GET 和 OPTIONS 上启用 CORS 时,我可以看到 Access-Control-Allow-Headers'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'
和 Access-Control-Allow-Origin* 是'*'
My Ajax call looks like below. I also tried copying the exact headers POSTMAN uses, which has the Authorization header set (which i have turned off in AWS for now) but i always get the same error above
我的 Ajax 调用如下所示。我还尝试复制 POSTMAN 使用的确切标头,其中设置了 Authorization 标头(我现在已在 AWS 中将其关闭),但我总是遇到上述相同的错误
var awsHeaders = {};
awsHeaders['X-Amz-Date'] = '20161127T171734';
$('#add, #cloud').click(function() {
$.ajax({
type: 'GET',
headers: awsHeaders,
dataType : "json",
url: '...',
success: function (res) {
console.log('response in GET:');
console.log(res);
},
error: function(data) {
console.log('in error');
console.log(data);
}
});
});
Can anyone shed light on what i might be missing?
任何人都可以阐明我可能缺少的东西吗?
Many thanks
非常感谢
UpdateSee answer below regarding how I solved this as per DigitalKapteain comments - by setting the 'Access-Control-Allow-Origin':'*' header in the response from my Lambda function. I looked for this in the AWS docs but couldn;t find it. This link describes the difference between Lambda and Lambda Proxy and explains what to do when using CORS https://serverless.com/framework/docs/providers/aws/events/apigateway/
更新请参阅下面关于我如何根据 DigitalKapteain 评论解决此问题的答案 - 通过在我的 Lambda 函数的响应中设置 'Access-Control-Allow-Origin':'*' 标头。我在 AWS 文档中寻找过这个,但找不到;此链接描述了 Lambda 和 Lambda 代理之间的区别,并解释了使用 CORS 时的操作https://serverless.com/framework/docs/providers/aws/events/apigateway/
回答by Digitalkapitaen
The response for the GET request to the Lambda function must also contain the Access-Control-Allow-Origin
header.
对 Lambda 函数的 GET 请求的响应还必须包含Access-Control-Allow-Origin
标头。
回答by Words Like Jared
Digitalkapitaen's answer is correct; here is the code to save someone the trouble of looking up how to set an HTTP response header in Lambda:
Digitalkapitaen 的回答是正确的;下面的代码可以省去查找如何在 Lambda 中设置 HTTP 响应标头的麻烦:
exports.handler = function(event, context, callback) {
callback(null, {
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "*"
}
});
};
回答by rickfarina
If this is still not working for you, be sure to JSON.stringify() your json object if you are using $.ajax. If not, you will still be returned an error that claims to be a CORS-related error. But if you send the same json object using Postman, the request will succeed. Try it out...
如果这仍然不适合您,如果您使用 $.ajax,请确保 JSON.stringify() 您的 json 对象。如果没有,您仍然会收到一个声称是 CORS 相关错误的错误。但是如果你使用 Postman 发送相同的 json 对象,请求就会成功。试试看...
回答by captainblack
For someone looking to integrate @Digitalkapitaen's solution in Flask, here's the code below:
对于希望在 Flask 中集成 @Digitalkapitaen 的解决方案的人,这里是下面的代码:
app = Flask(__name__)
cors = CORS(app, resources={r"/*": {"origins": "*"}})
@app.route("/")
def helloWorld():
return "Hello, cross-origin-world!"
Do install the flask-cors module by doing a:
通过执行以下操作安装flask-cors模块:
pip install -U flask-cors
回答by Black
In case you want to change only one header instead of replacing all headers as is shown in Words Like Jaredanswer. You can use this code:
如果您只想更改一个标题而不是替换所有标题,如Words Like Jared答案中所示。您可以使用此代码:
'use strict';
module.exports.handler = (event, context, callback) => {
const response = event.Records[0].cf.response;
const headers = response.headers;
headers['access-control-allow-origin'] = [{ key: 'Access-Control-Allow-Origin', value: "*" }];
return callback(null, response);
};
Another examples can be found on Adding HTTP Security Headers Using Lambda@Edge and Amazon CloudFront. It works same for normal Lambda function.
可以在使用 Lambda@Edge 和 Amazon CloudFront 添加 HTTP 安全标头中找到另一个示例。对于普通的 Lambda 函数,它的工作原理相同。