簡體   English   中英

AWS CDK CORS Cloudfront 錯誤 + Static S3 上的網站 + API 網關 + Z04A7DA3C5B134CAD85DAZ +EEBBD2 設置

[英]AWS CDK CORS error with Cloudfront + Static Website on S3 + API Gateway + Lambda + DynamoDb setup

我正在使用 AWS CDK (v1.87.1 (build 9eeaa93)) 將我的基礎設施定義為代碼。 我使用 C# 來定義我的 CDK 堆棧。

我將數據存儲在 DynamoDb 和 API 網關中,該網關由 Lambda 函數支持以讀取/寫入 DynamoDb。 這是我的后端。

我的前端是一個簡單的 static 網站(HTML + JS),托管在通過 CloudFront 分發的 AWS S3 上。

當我使用 curl 或在 AWS 控制台中獨立測試時,我的 API 工作正常。 但是,當我使用 fetch() 瀏覽器 API 從我的 static 網站頁面中調用 API 時,我收到以下錯誤(在瀏覽器中):

CORS 政策已阻止從源“https://abcdefg.cloudfront.net”訪問“https://xxxxxxxx.execute-api.ap-south-1.amazonaws.com/prod/Account”獲取:否'Access-Control-Allow-Origin' header 存在於請求的資源上。 如果不透明的響應滿足您的需求,請將請求的模式設置為“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 存儲桶部署代碼是:

        // 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 選項,但沒有任何成功。 我錯過了什么? 請幫忙。

我想到了。 錯誤出現在 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 處理程序響應。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM