1. 程式人生 > 其它 >Python pandas 入門 05 JSON

Python pandas 入門 05 JSON

跨域問題處理手冊

什麼是跨域?

在瀏覽器環境下,跨域是指一個域下的文件或指令碼試圖去請求另一個域下的資源。

域:由協議+域名+埠組成

正常情況下,如果我們通過ajax去請求另一個域下的資源時是不會成功的,瀏覽器預設會阻止這種行為,因為它違背了瀏覽器的同源策略。

同源策略(SOP: Same Origin Policy)是一種約定,由Netscape公司1995年引入瀏覽器,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,瀏覽器很容易受到XSS、CSFR等攻擊。

同源策略指 協議 + 域名 + 埠 三者相同,如果違背了同源策略那麼瀏覽器將限制獲取Cookie、LocalSgorage等、獲取DOM和JS物件、傳送Ajax請求。

 

跨域報錯對照表

Error: Access to XMLHttpRequest at 'http://xxxx' from origin 'http://xxxx' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

原因:瀏覽器執行預檢請求,後端介面返回302重定向,大部分瀏覽器將不繼續進行請求,直接報錯處理。出現該報錯有以下幾個原因:

  1. 介面對預檢請求進行了登入判斷,導致重定向到了登入頁

  2. 後端介面未實現options預檢請求,導致重定向到了404頁面

解決:

  1. 排查是否支援預檢請求,介面加上對options請求的支援

  2. 排查是否對預檢請求進行了登入判斷,去除掉登入判斷

 

Error: Access to XMLHttpRequest at 'https://xxxxxx' from origin 'http://xxxx' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

原因:介面響應header中未返回Access-Control-Allow-Origin跨域允許頭,導致瀏覽器對該請求直接block,就是我們俗稱的不支援跨域請求。

解決:出現這種情況需要找運維在Nginx中給對應的域名統一加上Access-Control-Allow-Origin: * | 具體域。PS: 為什麼由運維來處理?歷史原因運維和介面方各自新增造成了混亂,導致接口出現了另一個*,*跨域報錯,最終協商一致以後所有Access-Control-Allow-Origin都由運維來加,另外的幾個跨域header由介面方加上。

 

Error: Access to XMLHttpRequest at 'https://presale.111.com.cn/disaster/guardSwitch/query' from origin 'http://localhost:8000' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.

原因:Access-Control-Allow-Origin響應header重複添加了導致報錯,一般出現該原因是因為運維 和 介面方同時添加了Access-Control-Allow-Origin的響應header。

解決:Access-Control-Allow-Origin約定由運維統一新增,介面方應去掉程式碼中新增的Access-Control-Allow-Origin,如果程式碼中沒有新增該頭,但是也出現了該報錯,需要排查一下是否是閘道器層新增導致,找@周晨敏 同學幫忙排查下

 

Error: Access to XMLHttpRequest at 'https://presale.111.com.cn/disaster/guardSwitch/query' from origin 'http://localhost:8000' has been blocked by CORS policy: Request header field xxxx is not allowed by Access-Control-Allow-Headers in preflight response.

原因:發起的跨域請求添加了自定義的header,瀏覽器會檢查介面響應的access-control-allow-headers頭,造成改報錯可能是以下幾個原因

  1. 未攜帶access-control-allow-headers響應頭

  2. 攜帶的access-control-allow-headers響應的值中不包含 請求中自定義的header欄位xxxx

  3. 2015年之前的瀏覽器不支援access-control-allow-headers: * 配置,必須返回具體欄位

  4. 請求的content-type為application/json,返回的access-control-allow-headers中未包含content-type

解決:

  1. 檢查響應頭中是否已返回access-control-allow-headers,如未返回,請找介面方為介面新增access-control-allow-headers

  2. 檢查介面的access-control-allow-headers值中是否已包含自定義請求中的header,一般access-control-allow-headers值是以xxxx, xxxx, xxxx, xxxx形式,比如自定義請求中添加了auth: xxxxx 欄位,那麼響應access-control-allow-headers必須包含 auth, xxxx, ...

  3. 如果請求的content-type為application/json,同樣需要在access-control-allow-headers中包含content-type欄位

 

Error: Access to XMLHttpRequest at 'https://xxxx' from origin 'http://xxxx' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

原因:如果跨域請求設定了withCredentials:true, 瀏覽器發起請求的時候會攜帶上所在域的cookie資訊,同時跨域標準規定請求響應header中Access-Control-Allow-Origin不能設定*,必須設定為具體的跨域域名。

解決:如果業務需求確實需要跨域攜帶cookie資訊,找運維同學將Access-Control-Allow-Origin改成具體的發起域

 

Error: Access to XMLHttpRequest at 'https://xxxx' from origin 'http://xxxx' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

原因:跨域請求設定了withCredentials: true,響應header中未包含Access-Control-Allow-Credentials跨域頭,導致了報錯。

解決:介面方在跨域請求的headers中新增Access-Control-Allow-Credentials: true 允許攜帶瀏覽器請求攜帶cookie資訊。