在本地运行AWS SAM CLI时启用CORS

时间:2018-11-15 04:23:55

标签: amazon-web-services aws-lambda aws-api-gateway serverless aws-sam-cli

每当我尝试通过浏览器通过POST访问无服务器lambda函数时,都会收到错误消息

  

对预检请求的响应未通过访问控制检查:否>所请求的资源上存在“ Access-Control-Allow-Origin”标头。

当它是/GET时,它可以正常工作,我读到它是因为它没有发送飞行前请求。当我将其更改为POST时,它将失败。

我正在运行的命令:

sam local start-api

我的template.yaml是:

...

Resources:
    PropertiesFunction:
        Type: AWS::Serverless::Function
        Properties:
            CodeUri: target/service-0.0.1-SNAPSHOT.jar
            Handler: com.aws.PropertiesHandler::handleRequest
            Runtime: java8
            Events:
                PropertiesApi:
                    Type: Api
                    Properties:
                        Path: /properties
                        Method: post

...

如何在这些端点上启用CORS?

3 个答案:

答案 0 :(得分:5)

我有相同的错误,并且已经通过3个步骤修复了它。 (Java8中的AWS Lambda,SAM CLI v0.37.0)

  1. 为标题添加选项:
    Map<String, String> headers = new HashMap<>();
    headers.put("Content-Type", "application/json");
    headers.put("X-Custom-Header", "application/json");
    headers.put("Access-Control-Allow-Origin", "*");
    headers.put("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, PATCH, DELETE");
    headers.put("Access-Control-Allow-Headers", "X-Requested-With,content-type");
  1. 将Option Cors添加到template.yaml
    Globals:
      Function:
        Timeout: 20
      Api:
        Cors:
          AllowMethods: "'GET,POST,OPTIONS'"
          AllowHeaders: "'content-type'"
          AllowOrigin: "'*'"
          AllowCredentials: "'*'"
  1. 更新template.yaml中的属性资源功能
          Events:
            HelloWorld:
              Type: Api 
              Properties:
                # Path: /hello
                # Method: get
                Path: "/{proxy+}"
                Method: ANY

答案 1 :(得分:2)

通过在处理程序函数中向响应中显式添加以下标头,您应该能够解决此问题以进行本地测试:

    "Access-Control-Allow-Origin": "*"

您可以使用仅在本地运行时才添加标头的环境变量。

这是我拥有的处理函数中的一个简单的Python示例:

   if not all(field in values for field in required_fields):
    response = {
        'statusCode': 400,
        'body': json.dumps(
            {
                'message': 'Required data missing from request body'
            }
        )        
    }
    # explicitly add CORs headers for local testing
    response['headers'] = {"Access-Control-Allow-Origin": "*"}
    return response

这仅适用于本地测试,当您部署到API Gateway时,COR是通过API Gateway上的配置来处理的。

此解决方案对我一直有效,直到我还通过Cognito用户池向API添加了授权,目前正在尝试使用该用户池。

这是与此问题类似的帖子: How to Enable CORS for an AWS API Gateway Resource

Here's reference to it in the official AWS documentation.

答案 2 :(得分:2)

首先,您需要在template.yml中添加以下部分,以在API网关中启用cors:

Globals:
  Api:
    Cors:
      AllowMethods: "'GET,POST,OPTIONS'"
      AllowHeaders: "'content-type'"
      AllowOrigin: "'*'"
      AllowCredentials: "'*'"

然后在您的lambda函数响应中


        MultivaluedMap<String, Object> headers = responseContext.getHeaders();

        headers.add("Access-Control-Allow-Origin", "*");
        headers.add("Access-Control-Allow-Headers", requestContext.getHeaderString("Access-Control-Request-Headers"));
        headers.add("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,HEAD,OPTIONS");