Cloudfront + S3 上的静态网站 + API 网关 + Lambda + DynamoDb 设置出现 AWS CDK CORS 错误

问题描述 投票:0回答:1

我使用 AWS CDK(v1.87.1(版本 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个回答
0
投票

我想通了。错误发生在 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()(因为我之前在响应正文中发送了文本)。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.