首頁  >  文章  >  後端開發  >  最全ajax跨域解決方案

最全ajax跨域解決方案

小云云
小云云原創
2017-12-18 15:32:475324瀏覽

本文將和大家分享最全ajax跨域解決方案,從剛接觸前端開發起,<span style="font-size: 14px;">跨域</span>##這個詞就一直以很高的頻率在身邊重複出現,一直到現在,已經調試過N個跨域相關的問題了,16年時也整理過一篇相關文章,但是感覺還是差了點什麼,於是現在重新梳理了一下。

主題

關於跨域,有N種類型,本文只專注於ajax請求跨域<span style="font-size: 14px;"></span>(,ajax跨域只是屬於瀏覽器"同源策略"中的一部分,其它的還有Cookie跨域iframe跨域,LocalStorage跨域等這裡不做介紹),內容大概如下:

  • 什麼是ajax跨域

    • ##原理

    • 表現(整理了一些遇到的問題以及解決方案)

  • 如何解決ajax跨域

    • JSONP方式

    • CORS方式

    • 代理程式請求方式

  • #如何分析ajax跨域

    • http抓包的分析

    • #一些範例

#什麼是ajax跨域

ajax跨域的原理

ajax出現請求跨域錯誤問題,主要原因就是因為瀏覽器的「同源策略」,可以參考

#瀏覽器同源政策及其規避方法(阮一峰)

#CORS請求原理

CORS是一個W3C標準,全名為"跨域資源共享"(Cross-origin resource sharing)。它允許瀏覽器向跨來源伺服器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。

基本上目前所有的瀏覽器都實現了CORS標準,其實目前幾乎所有的瀏覽器ajax請求都是基於CORS機制的,只不過可能平時前端開發人員並不關心而已(所以說其實現在CORS解決方案主要是考慮後台該如何實現的問題)。

關於CORS,強烈建議閱讀 

跨域資源共享CORS 詳解(阮一峰)

另外,這裡也整理了一個實作原理圖(簡化版):

最全ajax跨域解決方案

#如何判斷是否為簡單請求?

瀏覽器將CORS請求分成兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)。只要同時滿足以下兩大條件,就屬於簡單請求。

  • 請求方法是以下三種方法之一:HEAD,GET,POST

  • HTTP的頭資訊不超出以下幾種欄位:

    • #Accept

    • Accept-Language

    • Content-Language

    • Last-Event-ID

    • Content-Type(只限於三個值application/x-www-form-urlencoded、     multipart/form-data、text/plain)

凡是不同時滿足上面兩個條件,就屬於非簡單請求。

ajax跨域的表現

說實話,當初整理過一篇文章,然後作為了一個解決方案,但是後來發現仍然有很多人還是不會。無奈只能耗時又耗力的調試。然而就算是我來分析,也只會根據對應的表現來判斷是否為跨域,因此這一點是很重要的。

ajax請求時,如果存在跨域現象,並且沒有進行解決,會有如下表現:(注意,是ajax請求,請不要說為什麼http請求可以,而ajax不行,因為ajax是伴隨著跨域的,所以只是http請求ok是不行的)

注意:具體的後端跨域設定請看題綱位置。

第一種現象:<span style="font-size: 14px;">No 'Access-Control-Allow-Origin' header is present on the requested resource</span>#,並且<span style="font-size: 14px;">The response had HTTP status code 404</span>

最全ajax跨域解決方案

#造成這種情況的原因如下:
  • 本次ajax請求是「非簡單請求」,所以請求前會發送一次預檢請求(OPTIONS)
  • 伺服器端後台介面沒有允許OPTIONS請求,導致無法找到對應介面位址

解決方案: 後端允許options請求

第二種現象:<span style="font-size: 14px;"></span>No 'Access-Control-Allow-Origin' header is present on the requested resource,並且<span style="font-size: 14px;"></span>##The response had HTTP status code 405

最全ajax跨域解決方案

這種現象和第一種有區別,這種情況下,後台方法允許OPTIONS請求,但是一些設定檔中(如<span style="font-size: 14px;"></span>安全設定 ),阻止了OPTIONS請求,才會導致這個現象

#解決方案: 後端關閉對應的安全配置

第三種現象:<span style="font-size: 14px;"></span>No 'Access-Control-Allow-Origin' header is present on the requested resource,並且<span style="font-size: 14px;"> </span>status 200

最全ajax跨域解決方案

#這種現象和第一種和第二種有區別,這種情況下,伺服器端後台允許OPTIONS請求,並且介面也允許OPTIONS請求,但是頭部匹配時出現不匹配現象

例如origin頭部檢查不符,比如少了一些頭部的支援(如常見的X-Requested-With頭),然後服務端就會將response回傳給前端,前端偵測到這個後就觸發XHR.onerror,導致前端控制台報錯

#解決方案: 後端增加對應的頭部支援

第四個現象:<span style="font-size: 14px;"></span>heade contains multiple values '* ,*'

最全ajax跨域解決方案

最全ajax跨域解決方案

#表現現象是,後台回應的http頭部訊息有兩個<span style="font-size: 14px;"></span>Access-Control-Allow-Origin:*

##說實話,這種問題出現的主要原因就是進行跨域配置的人不了解原理,導致了重複配置,如:

  • #常見於.net後台(一般在web .config中配置了一次origin,然後程式碼中又手動加入了一次origin(例如程式碼手動設定了返回*))

  • 常見於.net後台(在IIS和專案的webconfig中同時設定Origin:*)

#解決方案(一一對應):

  • 建議刪除程式碼中手動新增的*,只用專案配置中的即可

  • #建議刪除IIS下的設定* ,只用專案配置中的即可

    #

如何解決ajax跨域

一般ajax跨域解決就是透過JSONP解決或CORS解決,如以下:(注意,現在已經幾乎不會再使用JSONP了,所以JSONP了解下即可)

JSONP方式解決跨域問題

##jsonp解決跨域問題是一個比較古老的方案(實際中不推薦使用),這裡做簡單介紹(實際專案中如果要使用JSONP,一般會使用JQ等對JSONP進行了封裝的類別庫來進行ajax請求)

#實作原理

JSONP之所以能夠用來解決跨域方案,主要是因為