【Azure API 管理】從微信小程序訪問APIM出現200空響應的問題中發現CORS的屬性[terminate-unmatched-request]功能

問題描述

使用微信小程序調用APIM(API Management)中的接口,發現POST和PUT請求被攔截,返回的狀態碼爲200,可是無消息內容。jquery

在小程序中的調用JS代碼如:小程序

 

經過瀏覽器測試獲得的響應體爲:微信小程序

如上圖所見,微信小程序中發出的POST請求Status Code爲200 OK,但Response Length爲0。因爲在模擬器(Chrome瀏覽器模擬)並無如正常的CORS域名同樣報錯消息,因此沒法明確知道是什麼狀況致使這一問題。api

 

附:正常的CORS報錯信息爲:跨域

Access to XMLHttpRequest at 'https://test01.azure-api.cn/echo/resource1111' from origin 'https://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 https://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策略設置不匹配時:

  • 若是屬性設置爲true,請當即以200 OK響應做爲空白終止請求;不然,請執行如下操做:
  • 若是該屬性設置爲false,將檢查其餘的in-scope CORS策略應用它們。若是未找到CORS策略,請以空200 OK響應終止請求。

 

當GET或HEAD請求包含Origin報頭(並所以做爲跨域請求處理)且與CORS策略設置不匹配時:

  • 若是該屬性設置爲true,請當即以200 OK響應爲空終止該請求;不然,請執行如下操做:
  • 若是該屬性設置爲false,則容許請求正常進行,而且不要在響應中添加CORS標頭。

 

Source: https://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>http://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中,只有 https://localhost:9372 容許跨域訪問,而在微信小程序的POST的測試請求中,Request所攜帶的Origin值爲 http://127.0.0.1:27323 端口,因此該POST請求沒法配置CORS策略,返回200的空響應。當在CORS策略中添加 http://127.0.0.1:27323或者設置 * 後,請求成功。

 

 

參考資料

API Management cross domain policies:https://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>http://localhost:8080/</origin>
        <origin>http://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

使用狀況

此策略可在如下策略範圍中使用。

  • 策略節: 入站
  • 策略範圍: 全部範圍
相關文章
相關標籤/搜索