這篇文章主要介紹跨域方面的知識。javascript
說跨域以前先說說同源策略,同源策略是一種約定,幾乎全部現代瀏覽器都遵循了這種約定,它也是一種安全策略,確保非同源的請求沒法隨意請求,從而保證了網站的安全。同源須要保證協議,域名,端口都相同,只要有一個不一樣,那麼他們就不是同源的。雖然同源策略保證了安全性,但有時候咱們確實須要非同源之間相互訪問,好比在先後端分離的項目中,前端和後端的地址分別爲https://xwchris.me
和https://api.xwchris.me
。非同源之間跨域訪問就要用到CORS跨域方法。CORS全稱Cross Origin Resource Sharing
即跨域資源共享。html
如下是幾種與跨域相關的頭部,及簡單的介紹。前端
簡單請求要知足如下條件:java
GET
、HEAD
和POST
其中的一個Accept
、Accept-Language
、Content-Language
、Last-Event-ID
和Content-Type
且Content-Type
的值只限於application/x-www-form-urlencoded
、multipart/form-data
和text/plain
。瀏覽器發送簡單請求時會自動在請求頭部添加Origin
字段,表明訪問源。git
要支持CORS訪問須要服務器在響應頭中添加Access-Control-Allow-Origin
,可使用*
來表示容許全部域跨域訪問。github
非簡單請求與簡單請求最大的不一樣在於,它有一次預請求preflight
的過程,只有此次請求校驗經過,才能發送正常的請求。後端
預請求是OPTIONS
請求,瀏覽器會自動添加Access-Control-Allow-Headers
和Access-Control-Allow-Methods
。api
須要服務器返回的響應頭包括Access-Control-Allow-Headers
、Access-Control-Allow-Methods
和Access-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須要在請求的時候由開發者手動指定請求對象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請求,能夠放心食用。原文地址:傳送門