![](/img/trans.png)
[英]web api 2 CORS No 'Access-Control-Allow-Origin' header is present
[英]API Gateway CORS: no 'Access-Control-Allow-Origin' header
雖然已經通過 API Gateway 設置了 CORS 並設置了Access-Control-Allow-Origin
標頭,但在 Chrome 中嘗試從 AJAX 調用 API 時仍然收到以下錯誤:
XMLHttpRequest 無法加載http://XXXXX.execute-api.us-west-2.amazonaws.com/beta/YYYYY 。 請求的資源上不存在“Access-Control-Allow-Origin”標頭。 因此,Origin 'null' 不允許訪問。 響應具有 HTTP 狀態代碼 403。
我試圖通過Postman獲取 URL,它顯示上述標頭已成功傳遞:
從 OPTIONS 響應中:
如何從瀏覽器調用我的 API 而不恢復為 JSON-P?
我遇到同樣的問題。 我已經用了 10 小時來找出答案。
https://serverless.com/framework/docs/providers/aws/events/apigateway/
// handler.js
'use strict';
module.exports.hello = function(event, context, callback) {
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin" : "*", // Required for CORS support to work
"Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
},
body: JSON.stringify({ "message": "Hello World!" })
};
callback(null, response);
};
如果其他人仍然遇到這種情況 - 我能夠在我的應用程序中找到根本原因。
如果您使用自定義授權器運行 API-Gateway - API-Gateway 將在實際訪問您的服務器之前發送 401 或 403。 默認情況下 - 從自定義授權方返回 4xx 時,未為 CORS 配置 API 網關。
另外 - 如果您碰巧從通過 API Gateway 運行的請求中獲得0
或1
的狀態代碼,這可能是您的問題。
要修復 - 在 API 網關配置中 - 轉到“網關響應”,展開“默認 4XX”並在那里添加 CORS 配置標頭。 IE
Access-Control-Allow-Origin: '*'
確保重新部署您的網關- 瞧!
1)我需要做與@riseres 和其他一些更改相同的事情。這是我的響應標頭:
headers: {
'Access-Control-Allow-Origin' : '*',
'Access-Control-Allow-Headers':'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token',
'Access-Control-Allow-Credentials' : true,
'Content-Type': 'application/json'
}
2和
根據此文檔:
http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html
當您在 API Gateway 配置上為 lambda 函數使用代理時,post 或 get 方法沒有添加標頭,只有選項添加。 您必須在響應(服務器或 lambda 響應)中手動執行此操作。
3) 和
除此之外,我需要在我的 API 網關 post 方法中禁用“API Key Required”選項。
讓我的示例工作:我剛剛在生成的 nodejs Lambda 函數中插入了'Access-Control-Allow-Origin': '*', inside headers:{} 。 我沒有對 Lambda 生成的 API 層進行任何更改。
這是我的 NodeJS:
'use strict';
const doc = require('dynamodb-doc');
const dynamo = new doc.DynamoDB();
exports.handler = ( event, context, callback ) => {
const done = ( err, res ) => callback( null, {
statusCode: err ? '400' : '200',
body: err ? err.message : JSON.stringify(res),
headers:{ 'Access-Control-Allow-Origin' : '*' },
});
switch( event.httpMethod ) {
...
}
};
這是我的 AJAX 調用
$.ajax({
url: 'https://x.execute-api.x-x-x.amazonaws.com/prod/fnXx?TableName=x',
type: 'GET',
beforeSend: function(){ $( '#loader' ).show();},
success: function( res ) { alert( JSON.stringify(res) ); },
error:function(e){ alert('Lambda returned error\n\n' + e.responseText); },
complete:function(){ $('#loader').hide(); }
});
我剛剛在我的 lambda 函數響應中添加了標頭,它就像一個魅力
exports.handler = async (event) => {
const response = {
statusCode: 200,
body: JSON.stringify('Hey it works'),
headers:{ 'Access-Control-Allow-Origin' : '*' }
};
return response;
};
對於 Google 員工:
原因如下:
GET
/ POST
不會觸發預檢OPTIONS
方法,然后在用戶調用OPTIONS
時使用模擬響應發送Allow-Origin
標頭,但GET
/ POST
不會自動獲取Allow-Origin
Allow-Origin
標頭OPTIONS
的請求自行發送 CORS 標頭把它們加起來:
OPTIONS
OPTIONS
僅被瀏覽器用作檢查路徑上 CORS可能性的預防措施GET
/ POST
對我來說,最終有效的答案是 James Shapiro 的評論來自 Alex R 的答案(第二高投票)。 我首先遇到了這個 API 網關問題,嘗試獲取托管在 S3 中的靜態網頁以使用 lambda 處理聯系我們頁面並發送電子郵件。 只需檢查 [ ] Default 4XX 即可修復錯誤消息。
在我意識到 lambda 授權器失敗並且由於某種未知原因被轉換為 CORS 錯誤后,我開始工作。 對我的授權人的簡單修復(以及我應該首先添加的一些授權人測試)並且它起作用了。 對我來說,API 網關操作“啟用 CORS”是必需的。 這在我的 API 中添加了我需要的所有標頭和其他設置。
更改您的功能或代碼后 請按照以下兩個步驟操作。
首先啟用 CORS,然后每次都部署 API 。
在為POST
和OPTIONS
啟用 CORS 后部署代碼對我有用。
我正在運行aws-serverless-express
,在我的情況下需要編輯simple-proxy-api.yaml
。
在將 CORS 配置為https://example.com
之前,我只是交換了我的站點名稱並通過npm run setup
重新部署,它更新了我現有的 lambda/stack。
#...
/:
#...
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
#...
/{proxy+}:
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
#...
就我而言,由於我使用 AWS_IAM 作為 API 網關的授權方法,我需要授予我的 IAM 角色訪問端點的權限。
對我來說,因為我使用的是非常標准的 React fetch 調用,所以這可以使用上面的一些 AWS 控制台和 Lambda 修復來修復,但是我的 Lambda 返回了正確的標頭(我也使用了代理模式),我需要打包我的應用程序升級到 SAM 模板,所以我不能花時間在控制台上單擊。
我注意到所有 CORS 的東西都運行良好,直到我將 Cognito Auth 放到我的應用程序中。 我只是在使用越來越多的配置進行 SAM 包/SAM 部署時速度非常慢,直到它壞了,只要我將 Auth 添加到我的 API 網關,它就壞了。 我花了一整天的時間點擊像這樣的精彩討論,尋找一個簡單的解決方法,但最終不得不實際閱讀 CORS 正在做什么。 我將為您節省閱讀時間,並為您提供另一個簡單的解決方案(至少對我而言)。
以下是最終有效的 API 網關模板示例 (YAML):
Resources:
MySearchApi:
Type: AWS::Serverless::Api
Properties:
StageName: 'Dev'
Cors:
AllowMethods: "'OPTIONS, GET'"
AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
AllowOrigin: "'*'"
Auth:
DefaultAuthorizer: MyCognitoSearchAuth
Authorizers:
MyCognitoSearchAuth:
UserPoolArn: "<my hardcoded user pool ARN>"
AuthType: "COGNITO_USER_POOLS"
AddDefaultAuthorizerToCorsPreflight: False
注意底部的 AddDefaultAuthorizerToCorsPreflight。 根據我的閱讀,如果您的模板中沒有它,則默認為 True。 並且,當為 True 時,它會阻止正常的 OPTIONS 行為來宣布資源在允許的來源方面支持什么。 一旦我明確添加它並將其設置為 False,我的所有問題都解決了。
這意味着如果您遇到此問題並想要更完整地診斷它,您應該訪問 API Gateway 中的資源並檢查您的 OPTIONS 方法是否包含某種形式的身份驗證。 您的 GET 或 POST 需要身份驗證,但如果您的 OPTIONS 啟用了身份驗證,那么您可能會發現自己處於這種情況。 如果您在 AWS 控制台周圍單擊,請嘗試從 OPTIONS 中刪除,重新部署,然后進行測試。 如果您使用的是 SAM CLI,請嘗試我上面的修復。
確保您調用的是正確的路徑。
無論出於何種原因,命中不存在的路徑都可能導致 CORS 相關錯誤。 可能是因為404
在其響應中不包含 CORS 標頭。
感謝@jackko 對最初問題的評論。 這是我的問題。 聽起來很傻,但可能發生在任何人身上。
對於Python ,正如@riseres 所提到的,在導入 json 等之后......
// lambda handler
def hello(event, context, callback):
response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin" : "*", # Required for CORS support, to work, also you should instead specify the proper origin if credentials are mandatory
"Access-Control-Allow-Credentials" : True # Required for cookies, authorization headers with HTTPS
},
body: json.dumps({ "message": "Hello World!" })
}
callback(null, response);
}
此問題的另一個根本原因可能是 HTTP/1.1 和 HTTP/2 之間的差異。
症狀:部分用戶(並非全部)在使用我們的軟件時報告出現 CORS 錯誤。
問題:有時缺少Access-Control-Allow-Origin
標頭。
上下文:我們有一個 Lambda,專門用於處理OPTIONS
請求並使用相應的 CORS 標頭進行回復,例如Access-Control-Allow-Origin
匹配列入白名單的Origin
。
解決方案: API 網關似乎將 HTTP/2 調用的所有標頭轉換為小寫,但保持 HTTP/1.1 的大寫。 這導致對event.headers.origin
的訪問失敗。
檢查您是否也遇到此問題:
假設您的 API 位於https://api.example.com
,而您的前端位於https://www.example.com
。 使用 CURL,使用 HTTP/2 發出請求:
curl -v -X OPTIONS -H 'Origin: https://www.example.com' https://api.example.com
響應輸出應包括標題:
< Access-Control-Allow-Origin: https://www.example.com
使用 HTTP/1.1(或使用小寫的Origin
標頭)重復相同的步驟:
curl -v -X OPTIONS --http1.1 -H 'Origin: https://www.example.com' https://api.example.com
如果缺少Access-Control-Allow-Origin
標頭,您可能需要在讀取Origin
標頭時檢查區分大小寫。
除了其他評論之外,還需要注意的是從您的底層集成返回的狀態,以及是否為該狀態返回了 Access-Control-Allow-Origin 標頭。
執行“啟用 CORS”操作只會設置 200 個狀態。 如果您在端點上有其他人,例如 4xx 和 5xx,您需要自己添加標頭。
對於在 API Gateway 中使用 Cognito 授權器的用戶,實際上無需設置自定義網關響應。 API 網關會阻止預檢,因為它們在默認的 AWS 邏輯中是“未經授權的”。
幸運的是,有一個內置參數可以解決這個問題。 只需將AddDefaultAuthorizerToCorsPreflight: False
添加到您的 API Authorizer,API Gateway 將禁用預檢請求的身份驗證。 這是文檔和示例設置:
MyApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
Cors:
AllowHeaders: "'*'"
AllowMethods: "'*'"
AllowOrigin: "'*'"
Auth:
DefaultAuthorizer: MyCognitoAuthorizer
AddDefaultAuthorizerToCorsPreflight: False
Authorizers:
MyCognitoAuthorizer:
UserPoolArn: !GetAtt MyCognitoUserPool.Arn
對於未來的患者:
這個該死的問題再次困擾着我,這次是因為我發送了一個自定義標題:
let headers = {
'Content-Type': 'application/json',
'Is-Web': true,
Authorization: `Bearer ${accessToken}`,
};
這個“Is-Web”自定義標頭使 API Gateway 阻止了我的請求並將其屏蔽為 CORS 錯誤。 如果您要發送一個,只需將其刪除並測試即可。 幾乎因此失去了一整天的工作。
我已經有這個問題很長一段時間了。 我最終把它放到我的 python lambda 函數中
response ={
'statusCode': statusCode,
'headers':{
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
},
'body':json.dumps(body)
}
return response
我希望這可以幫助那里的人
就我而言,我只是將獲取請求 URL 寫錯了。 在serverless.yml
,你設置cors
到true
:
register-downloadable-client:
handler: fetch-downloadable-client-data/register.register
events:
- http:
path: register-downloadable-client
method: post
integration: lambda
cors: true
stage: ${self:custom.stage}
然后在 lambda 處理程序上發送標頭,但是如果在前端使提取請求出錯,則不會在響應中獲得該標頭,並且會收到此錯誤。 因此,請仔細檢查前面的請求 URL。
在 Python 中,您可以按照以下代碼進行操作:
{ "statusCode" : 200,
'headers':
{'Content-Type': 'application/json',
'Access-Control-Allow-Origin': "*"
},
"body": json.dumps(
{
"temperature" : tempArray,
"time": timeArray
})
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.