在文章“從微信小程式訪問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標記位:
跨域請求成功 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) | |
GET CORS 請求錯誤,不包含Access-Control-Allow-Origin 欄位 |
|
GET CORS 請求成功,包含Access-Control-Allow-Origin 欄位 |
對比二:非簡單請求 OPTIONS, POST
非簡單請求是那種對伺服器有特殊要求的請求,比如請求方法是POST, PUT
或DELETE
,或者Content-Type
欄位的型別是application/json
。非簡單請求的CORS請求,會在正式通訊之前,增加一次HTTP查詢請求,稱為"預檢"請求(preflight)。"預檢"請求用的請求方法是OPTIONS
,表示這個請求是用來詢問的。頭資訊裡面,關鍵欄位是Origin
,表示請求來自哪個源。
- 如果伺服器否定了"預檢"請求,會返回一個正常200的HTTP回應,但是沒有任何CORS相關的頭資訊欄位。這時,瀏覽器就會認定,伺服器不同意預檢請求,因此觸發一個錯誤.
- 如果伺服器收到"預檢"請求以後,檢查了
Origin
、Access-Control-Request-Method
和Access-Control-Request-Headers
欄位以後,確認允許跨源請求,就可以做出回應。關鍵的是Access-Control-Allow-Origin
欄位,表示可以請求資料。也可以為星號,表示同意任意跨源請求。
OPTIONS請求跨域失敗 | |
OPTIONS請求跨域成功 | |
POST 請求跨域成功 |
(PS: 以上資料在測試中通過Fiddler抓包獲取到OPTIONS和POST請求資料)
結論:
在遇見CORS報錯後,檢視請求的返回內容即可得出是否在服務端正確配置源站點
參考資料
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