【问题标题】:AWS CDK CORS error with Cloudfront + Static Website on S3 + API Gateway + Lambda + DynamoDb setupAWS CDK CORS 错误与 Cloudfront + S3 上的静态网站 + API 网关 + Lambda + DynamoDb 设置
【发布时间】:2021-05-07 14:20:58
【问题描述】:

我正在使用 AWS CDK (v1.87.1 (build 9eeaa93)) 将我的基础设施定义为代码。我使用 C# 来定义我的 CDK 堆栈。

我的数据存储在 DynamoDb 和一个由 Lambda 函数支持的 API 网关中,用于读取/写入 DynamoDb。这是我的后台。

我的前端是一个简单的静态网站 (HTML + JS),托管在通过 CloudFront 分发的 AWS S3 上。

当我使用 curl 或在 AWS 控制台中独立测试时,我的 API 工作正常。但是,当我在静态网站页面中使用 fetch() 浏览器 API 调用 API 时,我收到以下错误(在浏览器中):

访问获取 'https://xxxxxxxx.execute-api.ap-south-1.amazonaws.com/prod/Account' 来自 'https://abcdefg.cloudfront.net' 的来源已被阻止 CORS 策略:没有“Access-Control-Allow-Origin”标头出现在 请求的资源。如果不透明的响应满足您的需求,请将 请求模式为“no-cors”以获取禁用 CORS 的资源。

我的 CorsOptions 定义如下:

    var defaultCorsPreflightOptions = new CorsOptions() {
        AllowOrigins = Cors.ALL_ORIGINS,
        AllowMethods = Cors.ALL_METHODS,
        AllowHeaders = new [] {"*"},
        AllowCredentials = true,
        MaxAge = Duration.Days(0)
    };

我的API如下:

    var api = new RestApi(this, "my-api", new RestApiProps {
        RestApiName = "My Service",
        Description = "This is the service API"
    });

我的资源创建为预检添加了 CorsOption(在上面的错误消息中,“帐户”将是添加到根目录的资源):

        var resourceType = api.Root.AddResource(ent);
        resourceType.AddCorsPreflight(defaultCorsPreflightOptions);

我的 lambda 处理程序也有

if(method == "OPTIONS") {
  const response = {
    statusCode: 200,
    headers: {
      "Access-Control-Allow-Headers" : "Content-Type",
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "OPTIONS,POST,PUT,GET,DELETE"
    }
  };
  return response;      
} else if(method === "POST") {
     // ... omitted
}

调用REST API的JS客户端代码为:

    const response = await fetch(`${api_url}/${entity}`,{
        method: 'POST',
        mode: 'cors',
        body: item,
        headers: {
            'Content-Type': 'application/json'
        }
    });

附加到 CloudFront 分配的行为:

        // The cloudfront distribution for the website
        var behavior = new Behavior() {
            IsDefaultBehavior = true,
            AllowedMethods = CloudFrontAllowedMethods.ALL,
            MaxTtl = Duration.Seconds(0),
            MinTtl = Duration.Seconds(0),
            DefaultTtl = Duration.Seconds(0),
            Compress = false,
            ForwardedValues = new CfnDistribution.ForwardedValuesProperty() {
                QueryString = true,
                Headers = new [] {"Authorization", "Access-Control-Allow-Origin"}
            }
        };

我的 CloudFront 分布如下:

        var distribution = new CloudFrontWebDistribution(this, "StaticWebsiteDistribution", new CloudFrontWebDistributionProps() {
            OriginConfigs = new [] {
                new SourceConfiguration() {
                    S3OriginSource = new S3OriginConfig() {
                        S3BucketSource = bucket
                    },
                    Behaviors = new [] {
                        behavior
                    }
                }
            }
        });

我的 S3 Bucket 部署代码是:

        // The S3 bucket deployment for the website
        var deployment = new BucketDeployment(this, "WebsiteDeployment", new BucketDeploymentProps(){
            Sources = new [] {Source.Asset("./website")},
            DestinationBucket = bucket,
            Distribution = distribution
        });

我已尝试查看 AWS CDK 文档。我也尝试在 API 级别添加默认 CORS 选项,但没有任何成功。我错过了什么?请帮忙。

【问题讨论】:

    标签: amazon-web-services cors fetch aws-api-gateway aws-cdk


    【解决方案1】:

    我想通了。错误出现在 POST / GET / DELETE / PUT 方法的 Lambda 处理程序中。我需要返回标题(下面给出的示例):

      return {
        statusCode: 200,
        headers: {
          "Access-Control-Allow-Origin": "*",  // I was missing this
          "Content-Type": "application/json"   // and this
        },
        body: JSON.stringify({"id":`${id}`})   // and this was a string earlier
      };
    

    我在客户端处理 fetch() 响应时遇到了另一个错误。我使用的是 response.json() 而它应该是 response.text() (因为我之前在响应正文中发送文本)。

    我被 curl 响应(在我的测试中)误导了,它只是纯文本,而处理 fetch() 响应时存在 JSON 解析问题。

    要点:检查您的 Lambda 处理程序响应。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-10
      • 2021-05-21
      • 1970-01-01
      • 1970-01-01
      • 2019-07-30
      • 2019-03-16
      • 2021-05-23
      • 2018-06-28
      相关资源
      最近更新 更多