关于ajax:API网关CORS:没有’Access-Control-Allow-Origin’标头

API Gateway CORS: no 'Access-Control-Allow-Origin' header

尽管已通过API网关设置了CORS并且设置了Access-Control-Allow-Origin标头,但在尝试从Chrome中的AJAX调用API时仍会收到以下错误:

XMLHttpRequest cannot load http://XXXXX.execute-api.us-west-2.amazonaws.com/beta/YYYYY. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 403.

我试图通过Postman获取URL,它显示上面的标题已成功通过:

Passed headers

并从OPTIONS响应:

Response headers

如何在不恢复JSON-P的情况下从浏览器调用我的API?


我遇到了同样的问题。我用了10个小时才发现。

https://serverless.com/framework/docs/providers/aws/events/apigateway/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// handler.js

'use strict';

module.exports.hello = function(event, context, callback) {

const response = {
  statusCode: 200,
  headers: {
   "Access-Control-Allow-Origin" :"*", // Required for CORS support to work
   "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
  },
  body: JSON.stringify({"message":"Hello World!" })
};

callback(null, response);
};


如果还有其他人遇到这种情况 - 我能够在应用程序中找到根本原因。

如果您使用自定义授权程序运行API-Gateway,API-Gateway将在实际命中服务器之前发送401或403。默认情况下 - 从自定义授权程序返回4xx时,未为CORS配置API网关。

此外 - 如果您恰好从通过API网关运行的请求获取01的状态代码,这可能是您的问题。

要修复 - 在API网关配置中 - 转到"网关响应",展开"默认4XX"并在其中添加CORS配置标头。即

1
Access-Control-Allow-Origin: '*'

确保重新部署您的网关 - 瞧!


1)我需要和@riseres一样做以及其他一些更改。这是我的回复标题:

1
2
3
4
5
6
headers: {
            'Access-Control-Allow-Origin' : '*',
            'Access-Control-Allow-Headers':'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
            'Access-Control-Allow-Credentials' : true,
            'Content-Type': 'application/json'
        }

2和

根据这个文件:

http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html

在API网关配置上使用代理进行lambda函数时,post或get方法没有添加标题,只有选项可以。您必须在响应(服务器或lambda响应)中手动执行此操作。

3)和

除此之外,我需要在API网关post方法中禁用"API Key Required"选项。


让我的示例工作:我刚刚在生成的nodejs Lambda函数中插入了"Access-Control-Allow-Origin":'*',在header:{}内。我没有对Lambda生成的API层进行任何更改。

这是我的NodeJS:

1
2
3
4
5
6
7
8
9
10
11
12
13
'use strict';
const doc = require('dynamodb-doc');
const dynamo = new doc.DynamoDB();
exports.handler = ( event, context, callback ) => {
    const done = ( err, res ) => callback( null, {
        statusCode: err ? '400' : '200',
        body: err ? err.message : JSON.stringify(res),
        headers:{ 'Access-Control-Allow-Origin' : '*' },
    });
    switch( event.httpMethod ) {
        ...
    }
};

这是我的AJAX电话

1
2
3
4
5
6
7
8
9
10
$.ajax({
    url: 'https://x.execute-api.x-x-x.amazonaws.com/prod/fnXx?TableName=x',
    type: 'GET',
    beforeSend: function(){ $( '#loader' ).show();},
    success: function( res ) { alert( JSON.stringify(res) ); },
    error:function(e){ alert('Lambda returned error

' + e.responseText); },
    complete:function(){ $('#loader').hide(); }
});


在我意识到lambda授权人失败并因某些未知原因被转换为CORS错误后,我得到了我的工作。对我的授权人(以及我应该首先添加的一些授权人测试)的简单修复,并且它有效。对我来说,需要API网关操作"启用CORS"。这添加了我在API中所需的所有标题和其他设置。


如果你已经尝试过关于这个问题的一切都无济于事,那么你最终会在我所做的事情上结束。事实证明,亚马逊现有的CORS设置方向工作得很好......只是确保你记得重新部署! CORS编辑向导,即使有所有漂亮的小绿色复选标记,也不会对您的API进行实时更新。也许显而易见,但它让我困扰了半天。

enter image description here


此问题的另一个根本原因可能是HTTP / 1.1和HTTP / 2之间的差异。

症状:某些用户(并非所有用户)在使用我们的软件时都报告出现了CORS错误。

问题:有时会丢失Access-Control-Allow-Origin标题。

上下文:我们有一个Lambda,专门用于处理OPTIONS请求并使用相应的CORS头回复,例如Access-Control-Allow-Origin匹配列入白名单的Origin

解决方案:API网关似乎将所有标头转换为小写,用于HTTP / 2调用,但保持HTTP / 1.1的大小写。这导致对event.headers.origin的访问失败。

检查您是否也遇到此问题:

假设您的API位于https://api.example.com,并且您的前端位于https://www.example.com。使用CURL,使用HTTP / 2发出请求:

1
curl -v -X OPTIONS -H 'Origin: https://www.example.com' https://api.example.com

响应输出应包括标题:

< Access-Control-Allow-Origin: https://www.example.com

使用HTTP / 1.1(或使用小写Origin标头)重复相同的步骤:

1
curl -v -X OPTIONS --http1.1 -H 'Origin: https://www.example.com' https://api.example.com

如果缺少Access-Control-Allow-Origin标头,则可能需要在读取Origin标头时检查区分大小写。


就我而言,由于我使用AWS_IAM作为授权方法,因此我需要授予IAM角色权限以命中端点。


我正在运行aws-serverless-express,在我的情况下需要编辑simple-proxy-api.yaml

在将CORS配置为https://example.com之前,我只是换了我的站点名称并通过npm run setup重新部署,并更新了我现有的lambda / stack。

1
2
3
4
5
6
7
8
#...
/:
#...
method.response.header.Access-Control-Allow-Origin:"'https://example.com'"
#...
/{proxy+}:
method.response.header.Access-Control-Allow-Origin:"'https://example.com'"
#...

就我而言,我只是错误地写了获取请求URL。在serverless.yml上,将cors设置为true

1
2
3
4
5
6
7
8
9
register-downloadable-client:
    handler: fetch-downloadable-client-data/register.register
    events:
      - http:
          path: register-downloadable-client
          method: post
          integration: lambda
          cors: true
          stage: ${self:custom.stage}

然后在lambda处理程序上发送标题,但如果你在前端使获取请求错误,你就不会在响应中得到那个标题而你会得到这个错误。因此,请在前面仔细检查您的请求网址。


在Python中,您可以按照以下代码执行此操作:

1
2
3
4
5
6
7
8
9
10
11
{"statusCode" : 200,
'headers':
    {'Content-Type': 'application/json',
    'Access-Control-Allow-Origin':"*"
     },
"body": json.dumps(
    {
   "temperature" : tempArray,
   "time": timeArray
    })
 }


我发现了一个简单的解决方案

API网关>选择您的API端点>选择方法(在我的情况下,它是POST)

现在有一个下拉列表ACTIONS> Enable CORS ..选择它。

现在再次选择下拉列表ACTIONS> Deploy API(重新部署它)

enter image description here

有效 !