【Azure API 管理】從微信小程式訪問APIM出現200的空響應的問題中發現CORS的屬性[terminate-unmatched-request]功能
- 2021 年 3 月 8 日
- 筆記
- APIM, 【Azure API 管理】, terminate-unmatched-request, 空200請求狀態, CORS問題
問題描述
使用微信小程式調用APIM(API Management)中的介面,發現POST和PUT請求被攔截,返回的狀態碼為200,但是無消息內容。
在小程式中的調用JS程式碼如:

通過瀏覽器測試得到的響應體為:

如上圖所見,微信小程式中發出的POST請求Status Code為200 OK,但Response Length為0。由於在模擬器(Chrome瀏覽器模擬)並沒有如正常的CORS域名一樣報錯消息,所以無法明確知道是什麼情況導致這一問題。
附:正常的CORS報錯資訊為:
|
Access to XMLHttpRequest at '//test01.azure-api.cn/echo/resource1111' from origin '//localhost:44356' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. |
|
jquery.js:10099 POST //test01.azure-api.cn/echo/resource1111 net::ERR_FAILED |
問題原因
在遇見此類不明確問題時,需要找出問題點。所以此次問題的排查方向如下:
1) 在APIM的門戶中,使用Test功能測試介面(APIM門戶提供測試介面的功能)
2) 使用Postman工具,發送API請求進行測試
3) 在同樣的程式碼中訪問另一個API或者另一個APIM中的介面
通過測試,發現針對同一介面,第一,二的測試都是可以成功訪問。在第三個測試中,發現其他APIM的介面可以通過微信小程式正常訪問。通過以上步驟可以確定,是APIM的某些策略的設定影響了請求處理。所以在檢查在APIM的配置策略中,發現對API配置了CORS策略。而且通過刪除策略進行驗證(註:刪除策略後,可能需要等待45分鐘左右才會生效),POST,PUT請求從微信小程式中訪問成功。
在進一步分析APIM的CORS策略,有一個terminate-unmatched-request屬性,它的目的就是終止不匹配CORS設定的請求,默認值為True,它會返回一個空的200請求。
|
Name |
Description |
Required |
Default |
|
terminate-unmatched-request |
此屬性控制與CORS策略設置不匹配的跨域請求的處理。
當將OPTIONS請求作為pre-flight請求(預請求)處理且與CORS策略設置不匹配時:
當GET或HEAD請求包含Origin報頭(並因此作為跨域請求處理)且與CORS策略設置不匹配時:
Source: //docs.microsoft.com/en-us/azure/api-management/api-management-cross-domain-policies#CORS |
No |
true |
解決問題
通過根本原因的分析,發現APIM中配置的策略為:
<policies> <inbound> <base /> <cors allow-credentials="true"> <allowed-origins> <origin>//localhost:9372</origin> </allowed-origins> <allowed-methods preflight-result-max-age="300"> <method>GET</method> <method>POST</method> <method>PUT</method> <method>OPTIONS</method> <method>PATCH</method> <method>DELETE</method> </allowed-methods> <allowed-headers> <header>x-zumo-installation-id</header> <header>x-zumo-application</header> <header>x-zumo-version</header> <header>x-zumo-auth</header> <header>Authorization</header> <header>content-type</header> <header>accept</header> </allowed-headers> <expose-headers> <header>x-zumo-installation-id</header> <header>x-zumo-application</header> </expose-headers> </cors> </inbound> <backend> <base /> </backend> <outbound> <base /> </outbound> <on-error> <base /> </on-error> </policies>
返回空200請求的消息體Origin值截圖:

以上Allowed Origins中,只有 //localhost:9372 允許跨域訪問,而在微信小程式的POST的測試請求中,Request所攜帶的Origin值為 //127.0.0.1:27323 埠,所以該POST請求無法配置CORS策略,返回200的空響應。當在CORS策略中添加 //127.0.0.1:27323或者設置 * 後,請求成功。
參考資料
API Management cross domain policies://docs.microsoft.com/en-us/azure/api-management/api-management-cross-domain-policies#CORS
附錄一: APIM中CORS的說明
CORS
cors策略向操作或 API 添加跨源資源共享 (CORS) 支援,以便從基於瀏覽器的客戶端執行跨域調用。CORS 允許瀏覽器與伺服器交互,並確定是否允許特定的跨源請求(例如,通過某個網頁上的 JavaScript 對其他域執行 XMLHttpRequests 調用)。 與只允許同源請求相比,它的靈活性更高,而且比允許所有跨源請求更安全。
策略語句
<cors allow-credentials="false|true"> <allowed-origins> <origin>origin uri</origin> </allowed-origins> <allowed-methods preflight-result-max-age="number of seconds"> <method>http verb</method> </allowed-methods> <allowed-headers> <header>header name</header> </allowed-headers> <expose-headers> <header>header name</header> </expose-headers> </cors>示例
此示例演示如何支援預檢請求,例如那些具有自定義標頭或 GET 和 POST 之外的方法的預檢請求。 若要支援自定義標頭和其他 HTTP 謂詞,請使用
allowed-methods和allowed-headers部分,如以下示例所示。<cors allow-credentials="true"> <allowed-origins> <!-- Localhost useful for development --> <origin>//localhost:8080/</origin> <origin>//example.com/</origin> </allowed-origins> <allowed-methods preflight-result-max-age="300"> <method>GET</method> <method>POST</method> <method>PATCH</method> <method>DELETE</method> </allowed-methods> <allowed-headers> <!-- Examples below show Azure Mobile Services headers --> <header>x-zumo-installation-id</header> <header>x-zumo-application</header> <header>x-zumo-version</header> <header>x-zumo-auth</header> <header>content-type</header> <header>accept</header> </allowed-headers> <expose-headers> <!-- Examples below show Azure Mobile Services headers --> <header>x-zumo-installation-id</header> <header>x-zumo-application</header> </expose-headers> </cors>
元素
名稱 描述 必須 默認 cors 根元素。 是 不適用 allowed-origins 包含的 origin元素說明了跨域請求的允許來源。allowed-origins可能包含單個origin元素,該元素指定允許任何源的*,或者包含一個或多個內含 URI 的origin元素。是 不適用 origin 值可以是允許所有源的 *,或者是用於指定單個源的 URI。 URI 必須包括方案、主機和埠。是 如果 URI 中省略了埠,則埠 80 用於 HTTP,埠 443 用於 HTTPS。 allowed-methods 如果允許 GET 或 POST 之外的方法,則此元素是必需的。 包含 method元素,用於指定支援的 HTTP 謂詞。 值*指示所有方法。否 如果此部分不存在,則支援 GET 和 POST。 method 指定 HTTP 謂詞。 如果 allowed-methods部分存在,則至少一個method元素是必需。不適用 allowed-headers 此元素包含 header元素,用於指定可以包括在請求中的標頭的名稱。否 不適用 expose-headers 此元素包含 header元素,用於指定可以通過客戶端訪問的標頭的名稱。否 不適用 標頭 指定標頭名稱。 如果節存在,則 allowed-headers或expose-headers中至少一個header元素是必需。不適用 屬性
名稱 描述 必須 默認 allow-credentials 預檢響應中的 Access-Control-Allow-Credentials標頭將設置為此屬性的值,會影響客戶端在跨域請求中提交憑據的功能。否 false preflight-result-max-age 預檢響應中的 Access-Control-Max-Age標頭將設置為此屬性的值,會影響用戶代理快取預檢響應的功能。否 0 使用情況
- 策略節: 入站
- 策略範圍: 所有範圍

