AWS API 网关没有 'Access-Control-Allow-Origin' header 存在

AWS API Gateway No 'Access-Control-Allow-Origin' header is present

我遇到了 API 网关的问题,我已经浏览了所有其他关于此问题的 SO 答案,AWS 论坛并浏览了他们的文档,但仍然没有任何乐趣。

我正在尝试使用 AWS API 网关设置一个 API,它调用 Lambda 函数 reads/writes 到 DynamoDB 中的 table。

DynamoDB 的 Lambda 函数正在运行。我在 AWS 中创建了一个 API,并为其创建了 GET 和 OPTIONS 方法。我读到 AWS 不会仅对 GET/POST 执行 OPTIONS,但是当没有 OPTIONS 方法时,我在 ajax 调用中遇到预检错误,所以我添加了一个。

现在只是为了取得进展,我没有使用 API 密钥或授权。 我可以使用 POSTMAN 成功调用我的 GET 方法,其中 returns DynamoDB table.

的内容

但是当我尝试使用 JQuery ajax 调用时,我得到

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

我可以看到在网络选项卡下使用 Chrome 开发工具,OPTIONS 方法返回状态 200 和 GET returns 状态 200 但出现上述错误。

我尝试在 OPTIONS 和 GET 方法上启用 CORS,每次更改后都有 re-deployed API,尝试了以下 (http://enable-cors.org/server_awsapigateway.html) 但总是得到相同的结果控制台出错。

我正在从桌面上的文件执行 ajax 调用,因此 origin 为空,因为该页面将作为 JS 中的单个网页应用程序部署到 S3。

当我在 GET 和 OPTIONS 上启用 CORS 时,我可以看到 Access-Control-Allow-Headers 是 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token' 并且 Access-Control-Allow-Origin* 是 '*'

我的 Ajax 调用如下所示。我还尝试复制确切的 headers POSTMAN 使用,它设置了授权 header(我现在已经在 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);
        }

    });

});

任何人都可以阐明我可能遗漏了什么吗?

非常感谢

更新 请参阅下面关于我如何根据 DigitalKapteain 评论解决此问题的答案 - 通过在我的 Lambda 函数的响应中设置 'Access-Control-Allow-Origin':'*' header 。我在 AWS 文档中查找过这个但找不到。此 link 描述了 Lambda 和 Lambda Proxy 之间的区别,并解释了使用 CORS 时的操作 https://serverless.com/framework/docs/providers/aws/events/apigateway/

对 Lambda 函数的 GET 请求的响应还必须包含 Access-Control-Allow-Originheader.

Digitalkapitaen 的回答是正确的;这是为某人省去查找麻烦的代码 :

exports.handler = function(event, context, callback) {
    callback(null, {
        "statusCode": 200,
        "headers": { 
            "Access-Control-Allow-Origin": "*" 
        }
    });
};

如果这仍然不适合您,如果您使用的是 $.ajax,请务必 JSON.stringify() 您的 json 对象。如果不是,您仍然会返回一个错误,声称是与 CORS 相关的错误。但是如果你使用 Postman 发送相同的 json 对象,请求就会成功。试试看...

对于希望将@Digitalkapitaen 的解决方案集成到 Flask 中的人,请使用以下代码:

app = Flask(__name__)
cors = CORS(app, resources={r"/*": {"origins": "*"}})

@app.route("/")
def helloWorld():
  return "Hello, cross-origin-world!"

通过以下操作安装 flask-cors 模块:

pip install -U flask-cors

如果您只想更改一个 header 而不是替换所有 header,如 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);
};

可以在 Adding HTTP Security Headers Using Lambda@Edge and Amazon CloudFront 上找到其他示例。它对普通 Lambda 函数同样有效。

我遇到了同样的问题:在 S3 中配置了一个网站并尝试在 API 网关中进行 ajax 调用。在 API 网关中启用并部署了 CORS 并遇到了同样的问题,在 Lambda 代码中设置响应后 header 问题已解决。

这是我的示例 Lambda 代码片段:

 let response = {
        statusCode: responseCode,
        headers: {
            "x-custom-header" : "my custom header value",
            "Access-Control-Allow-Origin": "*"
        },
        body: JSON.stringify(responseBody)
    };
    console.log("response: " + JSON.stringify(response))
    return response;