跨域就這麼點事兒

這篇文章主要介紹跨域方面的知識。javascript

說跨域以前先說說同源策略,同源策略是一種約定,幾乎全部現代瀏覽器都遵循了這種約定,它也是一種安全策略,確保非同源的請求沒法隨意請求,從而保證了網站的安全。同源須要保證協議,域名,端口都相同,只要有一個不一樣,那麼他們就不是同源的。雖然同源策略保證了安全性,但有時候咱們確實須要非同源之間相互訪問,好比在先後端分離的項目中,前端和後端的地址分別爲https://xwchris.mehttps://api.xwchris.me。非同源之間跨域訪問就要用到CORS跨域方法。CORS全稱Cross Origin Resource Sharing即跨域資源共享。html

CORS跨域相關頭部

如下是幾種與跨域相關的頭部,及簡單的介紹。前端

  • Access-Control-Allow-Headers(請求頭,響應頭,預請求)(攜帶Cookie狀況下不能爲*)
  • Access-Control-Allow-Methods(請求頭,響應頭,預請求)(攜帶Cookie狀況下不能爲*)
  • Access-Control-Allow-Origin(響應頭,預請求/正常請求)(攜帶Cookie狀況下不能爲*)
  • Access-Control-Allow-Credentials(響應頭,預請求/正常請求)(攜帶Cookie狀況下要設置爲true)
  • Access-Control-Max-Age(響應頭,預請求)(單位s)

簡單請求的CORS

簡單請求要知足如下條件:java

  1. 請求方法必須是GETHEADPOST其中的一個
  2. HTTP信息不能超過如下幾種字段AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-TypeContent-Type的值只限於application/x-www-form-urlencodedmultipart/form-datatext/plain

瀏覽器發送簡單請求時會自動在請求頭部添加Origin字段,表明訪問源。git

要支持CORS訪問須要服務器在響應頭中添加Access-Control-Allow-Origin,可使用*來表示容許全部域跨域訪問。github

非簡單請求的CORS

非簡單請求與簡單請求最大的不一樣在於,它有一次預請求preflight的過程,只有此次請求校驗經過,才能發送正常的請求。後端

預請求

預請求是OPTIONS請求,瀏覽器會自動添加Access-Control-Allow-HeadersAccess-Control-Allow-Methodsapi

須要服務器返回的響應頭包括Access-Control-Allow-HeadersAccess-Control-Allow-MethodsAccess-Control-Allow-Origin跨域

除了Access-Control-Allow-Origin是必須的以外,其餘兩種只有在不符合簡單請求須要的時候服務器才須要添加,好比在簡單請求的基礎上自定義了一個請求頭X-xx-name: chris,那麼服務器只須要在響應頭中添加Access-Control-Allow-Headers。每種響應頭均可以使用*通配符來表示全部。瀏覽器

正常請求

預請求完以後就能夠發送正常請求了,正常請求的步驟與簡單請求一致,也須要添加Access-Control-Allow-Origin響應頭。

減小預請求次數

能夠經過設置Access-Control-Max-Aage來減小預請求的次數,須要包含在預請求的響應頭中,指定在該時間內預請求驗證有效,沒必要每次都進行預請求,它的單位是s。如Access-Control-Max-Age: 1728000,即有效期爲20天。

攜帶Cookie的請求

默認狀況下,跨域請求不會攜帶Cookie,若是要攜帶Cookie進行跨域請求須要請求方和接收方同時支持。爲了支持攜帶Cookie須要在請求的時候由開發者手動指定請求對象xhr.withCredentials=true。服務器響應頭須要包含Access-Control-Allow-Credentials: true,若是是非簡單請求,預請求也須要包含該頭部。

這裏須要注意的是,在這種狀況下全部須要的響應頭的值都不能是*,在須要的狀況下都須要明確指定。

其餘跨域方法

除了CORS,咱們還可使用JSONP技術來進行跨域,這是一種很古老的Hack。咱們都是知道script標籤能夠訪問任何域下的腳本,所以能夠利用這種方法來進行跨域,這須要服務器進行配合。舉個栗子🌰:

<script type="text/javascript"> function getName(name) { console.log(name); } </script>
<script src="http://api.xxx.com?callback=getName"></script>
複製代碼

請求服務器後服務器須要拿到callback字段的值,而後將要返回的值變成JSON,放入getName中。最終返回的值x像這個形式;getName({"name": "chris"}),這樣getName函數就能夠就能夠拿到相應的值。

JSONP相比CORS,只能進行GET請求,可是兼容性好一些。不過現代瀏覽器基本上都支持了CORS請求,能夠放心食用。原文地址:傳送門

相關文章
相關標籤/搜索