【Azure API 管理】APIM CORS策略設定後,跨域請求成功和失敗的Header對比實驗

路邊兩盞燈發表於2021-03-10

 

在文章“從微信小程式訪問APIM出現200空響應的問題中發現CORS的屬性[terminate-unmatched-request]功能”中分析了CORS返回空200的問題後,進一步對APIM的CORS策略進行驗證,深入學習<CORS 跨域資源共享>。

首先,我們已經學習到CORS需要瀏覽器和伺服器同時支援。目前,所有瀏覽器都支援該功能,整個CORS通訊過程,都是瀏覽器自動完成,不需要使用者參與。而服務端則不同,它是實現CORS通訊的關鍵。只要伺服器實現了CORS介面,就可以跨源通訊。本文中服務端就是Azure APIM (https://portal.azure.cn/#blade/HubsExtension/BrowseResource/resourceType/Microsoft.ApiManagement%2Fservice)。

 

在APIM中,是通過配置策略(Policy)來實現CORS設定的。在APIM門戶中由多種級別可以開啟CORS,可以根據API的使用情況靈活配置不同的跨域策略(cors policy)。

1) 產品級別(Products Policies):作用範圍為產品下的全部API

2) All APIs 級別 (Inbound processing):作用範圍為當前APIM中的所有API,所以在檢視策略時,一定要注意是否由全域性策略

3) All operstions 級別(Inbound processing):作用範圍為當前一個API下面的所有操作,如GET, POST, PUT.... 

4) One Operation級別 (最原子級,隻影響一個操作): 有效範圍僅對當前配置的一個操作

以上四個級別一一對應下圖中1,2,3,4標記位:

【Azure API 管理】APIM CORS策略設定後,跨域請求成功和失敗的Header對比實驗

 

跨域請求成功 VS 失敗

瀏覽器將CORS請求分成兩類:簡單請求(simple request)非簡單請求(not-so-simple request), 如何區別這兩者可參考:[HTTPS]跨域資源共享 CORS 詳解 -[轉自:阮一峰的網路日誌 » 首頁 » 檔案 http://www.ruanyifeng.com/blog/2016/04/cors.html]

 

對比一:簡單請求 GET

瀏覽器直接發出CORS請求。會在Requst頭資訊之中,增加一個Origin欄位,值為瀏覽器中的URL。伺服器根據這個值,決定是否同意這次請求。

  • 如果Origin指定的域名,不在許可範圍內,伺服器會返回一個正常的HTTP回應(200的空返回)。瀏覽器發現,這個回應的頭資訊沒有包含Access-Control-Allow-Origin欄位,就知道出錯了,從而丟擲一個CORS error錯誤。
  • 如果Origin指定的域名,在許可範圍內,伺服器返回的響應,會多出幾個Access-Control-* 頭資訊欄位。
CORS error 瀏覽器表現(開啟開發者模式視窗可見 F12) 【Azure API 管理】APIM CORS策略設定後,跨域請求成功和失敗的Header對比實驗
GET CORS 請求錯誤,不包含Access-Control-Allow-Origin欄位 【Azure API 管理】APIM CORS策略設定後,跨域請求成功和失敗的Header對比實驗
GET CORS 請求成功,包含Access-Control-Allow-Origin欄位 【Azure API 管理】APIM CORS策略設定後,跨域請求成功和失敗的Header對比實驗

 

 

對比二:非簡單請求 OPTIONS, POST

非簡單請求是那種對伺服器有特殊要求的請求,比如請求方法是POST, PUTDELETE,或者Content-Type欄位的型別是application/json。非簡單請求的CORS請求,會在正式通訊之前,增加一次HTTP查詢請求,稱為"預檢"請求(preflight)。"預檢"請求用的請求方法是OPTIONS,表示這個請求是用來詢問的。頭資訊裡面,關鍵欄位是Origin,表示請求來自哪個源。

  • 如果伺服器否定了"預檢"請求,會返回一個正常200的HTTP回應,但是沒有任何CORS相關的頭資訊欄位。這時,瀏覽器就會認定,伺服器不同意預檢請求,因此觸發一個錯誤.
  • 如果伺服器收到"預檢"請求以後,檢查了OriginAccess-Control-Request-MethodAccess-Control-Request-Headers欄位以後,確認允許跨源請求,就可以做出回應。關鍵的是Access-Control-Allow-Origin欄位,表示可以請求資料。也可以為星號,表示同意任意跨源請求。
OPTIONS請求跨域失敗 【Azure API 管理】APIM CORS策略設定後,跨域請求成功和失敗的Header對比實驗
OPTIONS請求跨域成功 【Azure API 管理】APIM CORS策略設定後,跨域請求成功和失敗的Header對比實驗 
POST 請求跨域成功 【Azure API 管理】APIM CORS策略設定後,跨域請求成功和失敗的Header對比實驗

(PS: 以上資料在測試中通過Fiddler抓包獲取到OPTIONS和POST請求資料)

結論:

在遇見CORS報錯後,檢視請求的返回內容即可得出是否在服務端正確配置源站點 【Azure API 管理】APIM CORS策略設定後,跨域請求成功和失敗的Header對比實驗​​​​​ 【Azure API 管理】APIM CORS策略設定後,跨域請求成功和失敗的Header對比實驗 ​​​​​​​【Azure API 管理】APIM CORS策略設定後,跨域請求成功和失敗的Header對比實驗​​​​​​​ 【Azure API 管理】APIM CORS策略設定後,跨域請求成功和失敗的Header對比實驗 ​​​​​​​【Azure API 管理】APIM CORS策略設定後,跨域請求成功和失敗的Header對比實驗 ​​​​​​​【Azure API 管理】APIM CORS策略設定後,跨域請求成功和失敗的Header對比實驗​​​​​​

 

 

參考資料

API Management cross domain policies:https://docs.microsoft.com/en-us/azure/api-management/api-management-cross-domain-policies#CORS

跨域資源共享 CORS 詳解:http://www.ruanyifeng.com/blog/2016/04/cors.html

 

 

 

 

 

相關文章