簡體   English   中英

盡管設置了標頭,但調用 API 網關返回 CORS 錯誤

[英]Call to API Gateway returning CORS error despite headers being set

我有一個與 Lambda function 集成的 API 網關(HTTP 類型)。我正嘗試從本地主機調用 function,如下所示:

const jwt = getAuthToken();
const formBody = new FormData();
formBody.set('user', 'test');

const res = await fetch('https://example.execute-api.eu-west-1.amazonaws.com/default/GetShareValue', {
method: 'POST',
body: formBody,
headers: {
   'Authorization': jwt
   }
});

但是,我收到此錯誤消息:

CORS 策略阻止了從來源“http://localhost:3000”訪問“https://example.execute-api.eu-west-1.amazonaws.com/default/GetShareValue”:對預檢的響應請求未通過訪問控制檢查:請求的資源上不存在“Access-Control-Allow-Origin”header。 如果不透明的響應滿足您的需求,請將請求的模式設置為“no-cors”以獲取禁用 CORS 的資源。

我知道不正確的 CORS 設置會阻止瀏覽器顯示 Lambda function 返回的內容。 但是,我的 API 網關指定了 CORS 設置:

在此處輸入圖像描述

根據此線程,在 Lambda 函數的響應中設置標頭很重要。 我已將它們設置為相同。 這是我的 Lambda function:

exports.handler = async (event, context) => {
    let body;
    let statusCode = '200';
    const headers = {
        'Content-Type': 'application/json',
        "Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,X-Amz-Security-Token,Authorization,X-Api-Key,X-Requested-With,Accept,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Access-Control-Allow-Headers",
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "*",
        "X-Requested-With": "*"
    };

try {
    body = "Success!!";
} catch (err) {
    statusCode = '400';
    body = err.message;
} finally {
    body = JSON.stringify(body);
}

return {
    statusCode,
    body,
    headers,
};

};

我可以在 Postman 中調用這個端點——它不關心 CORS——所以我知道它在工作。 我開始認為這是 AWS 本身的一個錯誤。

為了@peter n 的利益回答我自己的問題。

最后我放棄了HTTP API網關。 我相信 AWS 中存在一個錯誤,因為當我通過 REST API 觸發它時,完全相同的 Lambda function 起作用了。這就是我所做的。

  1. 新建一個 API 網關
  2. Select API 網關的類型為REST API 我之前選擇了 HTTP。REST API 給了我們更多的控制權; HTTP API 很簡單(便宜 70%)
  3. 在“資源”頁面上,單擊“操作”>“創建資源”
  4. 創建資源; 如果您看到任何提到 CORS 的復選框,請選中它。 我不記得這是否發生在這個階段。
  5. 然后單擊“操作”>“創建方法”
  6. Select 除“Any”之外的任何方法(如 POST、GET 等)。 這很重要——如果你 select “Any” CORS 還有其他問題。為什么? 誰知道,AWS 是一個用戶不友好的平台。
  7. 一旦你配置了方法並讓它在你的 Lambda function(或你正在集成的任何東西)上觸發,用 Postman 之類的東西測試它,它不關心 CORS。
  8. 最后,要使 CORS 正常工作,請單擊 Actions > Enable CORS

我輸入了以下設置:

方法:POST

訪問控制允許方法:選項,POST

Access-Control-Allow-Headers :'Content-Type,X-Amz-Date,X-Amz-Security-Token,Authorization,X-Api-Key,X-Requested-With,Accept,Access-Control-Allow-Methods ,訪問控制允許來源,訪問控制允許標頭'

訪問控制允許來源:'*'

然后單擊“啟用 CORS 並替換現有的 CORS 標頭”。

你還沒有完成。 如果您的目標是 Lambda function,這仍然無法解決問題。您需要將 CORS 標頭添加到 Lambda 的實際響應中。

這是我的 Lambda 的完整代碼:

exports.handler = async (event, context) => {
   let body = JSON.stringify('Success!');
   let statusCode = '200';
   const headers = {
      'Content-Type': 'application/json',
      "Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,X-Amz-Security-Token,Authorization,X-Api-Key,X-Requested-With,Accept,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Access-Control-Allow-Headers",
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "*",
      "X-Requested-With": "*"
   };
    
   return {
      statusCode,
      body,
      headers,
   };
};

我不確定您在 Lambda 中返回的 CORS 設置是否與您在 AWS 控制台中應用的 CORS 設置相同。

這真是令人頭疼,除非我做錯了什么,否則 AWS 已經非常糟糕地實現了這一點。

更新:在遇到更多問題后,我想我會更新我對 state 的回答,您提出的請求似乎也會影響 CORS。我正在對我的 API 進行更改,CORS 錯誤又開始發生; 最終,唯一的解決方案是刪除我發送給 AWS 的請求中的一些標頭。

這導致了 CORS 錯誤:

const res = await fetch('https://123.execute-api.eu-west-1.amazonaws.com/test', {
   method: 'POST',
   headers: {
      'Authorization': jwt,
      "Access-Control-Allow-Origin": "*" // This had to be removed to fix the CORS error
   }
});

如您所見,我在我的 API 的出站請求中指定了Access-Control-Allow-Origin 。這一直存在並且從未引起問題,但現在看來我可以在請求中注釋和取消注釋該行並獲取/不-得到 CORS 錯誤。

更新 #2:進一步更新,以拯救可能為此而用頭撞牆的任何人。在向現有 API 網關添加新源和方法后,請務必單擊“ Actions > Deploy API ,以便您的更改實際生效。

AWS 確實需要清理 API 網關和 Lambda 的整個 UI。根本不清楚您有未發布的更改,甚至需要發布; 用戶界面使任何更改看起來都立即生效。

主要問題在於 Options 方法提供的答案。 出於某種原因,至少在我的情況下,模擬響應無法正常工作,因此我將其與 lambda 鏈接,其唯一目的是使用 200 代碼進行響應並返回所有必要的標頭。

因此,您要做的是,在啟用了 CORS 的資源的選項方法中,將集成請求更改為 Lambda。

完成后,我們必須開發 lambda,以便它返回 200 作為響應並接受所有必要的標頭:

{
    'statusCode': 200,
    'headers': {
        'Content-Type': 'application/json',
          "Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,X-Amz-Security-Token,Authorization,X-Api-Key,X-Requested-With,Accept,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Access-Control-Allow-Headers",
          "Access-Control-Allow-Origin": "*",
          "Access-Control-Allow-Methods": "*",
          "X-Requested-With": "*"
    },
    'body': json.dumps({})
}

暫無
暫無

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

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