从S3上的静态站点进行POST时,AWS API Gateway端点会出现CORS错误

时间:2015-12-17 01:06:39

标签: amazon-s3 cors aws-api-gateway

我创建了一个带有Serverless(serverless.com)的API端点,我通过API Gateway公开了它。虽然我已经从

启用了CORS,但我收到了以下错误
  

XMLHttpRequest无法加载   https://xxxxxxxxx.execute-api.us-west-2.amazonaws.com/development/signup。   No' Access-Control-Allow-Origin'标题出现在请求的上   资源。起源   ' http://yyyyyyyyy.com.s3-website-us-east-1.amazonaws.com'因此   不允许访问。

AWS API Gateway settings for the endpoint

尽管我已经设置了origin标头,但是当我使用Postman发出请求时,我没有收到任何错误。我该如何解决这个问题?

9 个答案:

答案 0 :(得分:13)

我们现在有一个错误,其中对API网关的失败请求不会包含相应的CORS标头,这会掩盖请求中的实际错误。

我添加了肯所说的内容,并确保您已经使用Postman或其他不是浏览器的客户端彻底测试了控制台中的API和资源以及已部署的版本。我希望API本身存在问题,并且您的CORS配置是正确的。

答案 1 :(得分:6)

正如Jack Kohn所指出的,AWS控制台没有在非200响应上添加CORS标头,显然不允许您添加任何自定义标头。

我能够通过导出到swagger并手动编辑文件(刚刚复制了200响应)并将其导回来,在失败的请求上启用CORS头。

回复应如下所示:

  responses:
    200:
      description: "200 response"
      schema:
        $ref: "#/definitions/Empty"
      headers:
        Access-Control-Allow-Origin:
          type: "string"
    401:
      description: "401 response"
      schema:
        $ref: "#/definitions/Empty"
      headers:
        Access-Control-Allow-Origin:
          type: "string"
  x-amazon-apigateway-integration:
    responses:
      default:
        statusCode: "200"
        responseParameters:
          method.response.header.Access-Control-Allow-Origin: "'*'"
        responseTemplates:
          application/json: "__passthrough__"
      Authentication Failed.*:
        statusCode: "401"
        responseParameters:
          method.response.header.Access-Control-Allow-Origin: "'*'"
        responseTemplates:
          application/json: "__passthrough__"

希望这有帮助。

答案 2 :(得分:3)

我会通过在AWS控制台中检查您的API来开始进行故障排除,以确保无服务器以您期望的方式注册所有内容。

  1. 加载AWS控制台并导航至API网关服务。
  2. 点击API将其打开。
  3. 查找您的/注册资源
  4. 确保在/ signup
  5. 下看到OPTIONS方法
  6. 单击包含选项的每个资源并检查以下内容:

    一个。单击“集成响应”,单击表格第一行中的箭头200以将其打开。

    湾单击箭头以打开标题映射

    ℃。确保您看到Access-Control-Allow-Origin映射到' *'

  7. 如果您发现其中一种方法缺少此标头,则快速解决方法是单击/注册资源并单击“启用CORS”按钮。 AWS将为您构建OPTIONS和所有方法的标头映射。当然,你仍然需要弄清楚为什么无服务器没有为你设置的东西,但这至少会让你前进。

    关于启用CORS按钮的另一个注意事项,如果您稍后添加其他方法,则必须再次单击它以重新运行该工具以使用CORS设置新方法。

答案 3 :(得分:2)

当发布' POST'时,我正在努力解决同样的问题。到API网关。但我找到了解决这个问题的方法。

为方法资源启用CORS后,在添加必要的Headers之后,例如'访问控制允许来源' =' *'通配符,它​​仍然失败。

转到您要调用的资源的选项,' GET',' POST'等等。点击"方法请求"该资源的窗格,设置API密钥= FALSE,不要将API密钥设置为true。这将导致CORS错误。

原因,OPTIONS在技术上不是一种方法,它是一个执行Preflight请求的浏览器函数,因此在Preflight期间浏览器不知道要发送什么API密钥,它只知道在响应返回浏览器后才知道' Access-Control-Allow-Origin' =' *'然后它将查找HTTP req的代码以使X-Api-Key的setHeaders =某个值。

注意:调用方法本身,' POST'等...可以有API Key = True,这是完全正常的。

希望这能帮助那些正在努力奋斗的人一段时间:)

答案 4 :(得分:2)

我遇到了这个问题...我启用了CORS,测试工作正在发送标题,但是当我从我的应用程序调用它时它失败并且没有在响应中找到标题。

这是因为在设置CORS后你必须部署API。我深入研究了API,一切都很好。

答案 5 :(得分:0)

响应应该有,如果您使用的是AWS lamda,请按如下方式设置响应标头。 API网关上的配置不起作用

headers: {
            'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*',
        },

答案 6 :(得分:0)

我接近同样的问题,因为我在另一个问题中发布,我需要在我的回复中添加以下标题:

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'
        }

并且,根据此文档:

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

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

除此之外,我需要在我的API网关帖子方法中禁用“API Key Required”选项,就像这里的人已经说过的那样。

答案 7 :(得分:0)

您需要为所有方法启用CORS。意思是,您需要为所有方法添加以下三个标题

            "headers": {
            "Access-Control-Allow-Origin": {
                "type": "string"
            },
            "Access-Control-Allow-Methods": {
                "type": "string"
            },
            "Access-Control-Allow-Headers": {
                "type": "string"
            }
        }

将这些标头添加到JSON中的所有方法是一项繁琐的工作。

在Java中创建了一个实用程序,它自动将这些头添加到Swagger JSON中。您可以在将其导入API网关之前运行它,并导入在所有方法中启用了CORS的输出JSON

https://github.com/anandlalvb/SwaggerToAPIGateway

我希望这个实用程序可以帮助任何寻找此功能的人轻松完成。

答案 8 :(得分:0)

我花了一些时间在网上搜索后,才使用AWS sdk进行上传,但我偶然发现了该线程。感谢@lsimoneau 45581857,事实证明确实发生了同样的事情。我只是通过附加region属性将我的请求Url指向了我的存储桶上的区域,它就起作用了。

 const s3 = new AWS.S3({
 accessKeyId: config.awsAccessKeyID,
 secretAccessKey: config.awsSecretAccessKey,
 region: 'eu-west-2'  // add region here });