API Gateway CORS: no 'Access-Control-Allow-Origin' header
尽管已通过API网关设置了CORS并且设置了
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,它显示上面的标题已成功通过:
并从OPTIONS响应:
如何在不恢复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网关运行的请求获取
要修复 - 在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进行实时更新。也许显而易见,但它让我困扰了半天。
此问题的另一个根本原因可能是HTTP / 1.1和HTTP / 2之间的差异。
症状:某些用户(并非所有用户)在使用我们的软件时都报告出现了CORS错误。
问题:有时会丢失
上下文:我们有一个Lambda,专门用于处理
解决方案:API网关似乎将所有标头转换为小写,用于HTTP / 2调用,但保持HTTP / 1.1的大小写。这导致对
检查您是否也遇到此问题:
假设您的API位于
1 | curl -v -X OPTIONS -H 'Origin: https://www.example.com' https://api.example.com |
响应输出应包括标题:
使用HTTP / 1.1(或使用小写
1 | curl -v -X OPTIONS --http1.1 -H 'Origin: https://www.example.com' https://api.example.com |
如果缺少
就我而言,由于我使用AWS_IAM作为授权方法,因此我需要授予IAM角色权限以命中端点。
我正在运行
在将CORS配置为
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。在
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(重新部署它)
有效 !