前端必備HTTP技能之跨站資源共享(CORS)技術(shù)詳解

CORS(Cross-origin resource sharing)是一種安全機(jī)制,允許其他域請(qǐng)求獲取到當(dāng)前域中web頁面中的限制資源。web頁面可以自由的嵌入圖片,樣式,腳本,iframe,視頻等資源,但是由于同源策略的限制,跨域請(qǐng)求會(huì)被限制。

CORS定義了一種方式,通過這種方式瀏覽器和服務(wù)器可以互相確定允許跨域請(qǐng)求是否是安全的。這樣就比單純的同源請(qǐng)求有更多的自由度,也可以實(shí)現(xiàn)更多的功能,而且也比允許全部的跨域請(qǐng)求更安全。CORS是W3C中的一個(gè)推薦標(biāo)準(zhǔn)。

CORS原理
CORS標(biāo)準(zhǔn)介紹了新的HTTP headers,在瀏覽器和服務(wù)器都獲得授權(quán)的情況下,這些headers給它們提供了一種訪問遠(yuǎn)程URL的方式。盡管服務(wù)器可以執(zhí)行一些驗(yàn)證和授權(quán),但是瀏覽器也有責(zé)任來支持這些headers,遵循限制。

對(duì)于AJAX和可以修改數(shù)據(jù)的HTTP請(qǐng)求方法來說,規(guī)范規(guī)定瀏覽器預(yù)檢查請(qǐng)求,通過請(qǐng)求頭中的OPTIONS方法獲取服務(wù)端支持的請(qǐng)求方法,然后得到服務(wù)器的批準(zhǔn)之后,使用真實(shí)的HTTP請(qǐng)求方法發(fā)送真實(shí)的請(qǐng)求。服務(wù)器也可以通知客戶端是否需要隨請(qǐng)求發(fā)送證書(包括Cookies和HTTP認(rèn)證數(shù)據(jù))。


示意圖
示意圖

簡(jiǎn)單示例
當(dāng)支持CORS的瀏覽器嘗試發(fā)起跨域請(qǐng)求時(shí):
1.瀏覽器發(fā)送OPTIONS請(qǐng)求,并在HTTP頭中指定Origin,Origin的值是提供父級(jí)頁面的域。當(dāng)前域http://www.foo.com中的頁面嘗試獲取域http://www.bar.com中的用戶數(shù)據(jù)時(shí),下面的請(qǐng)求頭將會(huì)發(fā)送給http://www.bar.com域:

Origin:http://www.foo.com

2.服務(wù)器可能會(huì)有下面的響應(yīng):

  • 響應(yīng)頭中的Access-Control-Allow-Origin標(biāo)識(shí)允許那個(gè)來源站點(diǎn)。例如:
    Access-Control-Allow-Origin: http://www.foo.com
  • 如果服務(wù)器不支持跨域請(qǐng)求會(huì)返回錯(cuò)誤頁面
  • 響應(yīng)頭中的Access-Control-Allow-Origin如果是通配符則表示允許任何域訪問:
    Access-Control-Allow-Origin: *

當(dāng)一個(gè)頁面或者API是完全公開的,并且可以被任何人或者任意站點(diǎn)上的代碼訪問時(shí),通配符同源策略是一個(gè)好的方法。例如在公共托管服務(wù)上的免費(fèi)可用的Google字體。

通配符*意味著服務(wù)器不需要請(qǐng)求提供憑證,有意義的HTTP身份驗(yàn)證,客戶端的SSL驗(yàn)證,也不允許發(fā)送cookies。

注意在CORS架構(gòu)中,Access-Control-Allow-Origin頭是外部web服務(wù)器(http://www.bar.com)設(shè)置的,而不是源web服務(wù)器(http://www.foo.com)設(shè)置的。CORS允許外部web服務(wù)器授權(quán)web應(yīng)用使用它的服務(wù),不控制web應(yīng)用訪問外部服務(wù)。

預(yù)檢查示例
執(zhí)行某些類型的跨域ajax請(qǐng)求時(shí),支持CORS的瀏覽器會(huì)插入一個(gè)額外的預(yù)檢查請(qǐng)求來決定是否有權(quán)限執(zhí)行相應(yīng)的動(dòng)作。

OPTIONS /
Host: bar.com
Origin: http://foo.com

如果bar.com想要接收這種行為,它可能會(huì)回復(fù)下面的響應(yīng)頭:

Access-Control-Allow-Origin: http://foo.com
Access-Control-Allow-Methods: PUT, DELETE

Headers
CORS相關(guān)的HTTP頭如下:

請(qǐng)求頭

  • Origin
  • Access-Control-Request-Method
  • Access-Control-Request-Headers

響應(yīng)頭

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Credentials
  • Access-Control-Expose-Headers
  • Access-Control-Max-Age
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers

瀏覽器支持情況
瀏覽器支持詳情可以參考can I use網(wǎng)站上面的統(tǒng)計(jì),點(diǎn)這里查看詳情。

歷史
跨域支持最早是在2004年的VoiceXML中作為一個(gè)雜項(xiàng)提出的,主要是為了支持VoiceXML瀏覽器可以安全獲取跨域數(shù)據(jù)。機(jī)制本質(zhì)上是通用的,在VoiceXML中沒有具體化,隨后被分配到一個(gè)實(shí)現(xiàn)備忘中。然后主要瀏覽器廠商參與的W3C的WebApps工作組開始把備忘錄規(guī)范化成W3C工作草案,最后才慢慢變成W3C推薦標(biāo)準(zhǔn)。

CORS和JSONP對(duì)比
CORS可以作為JSONP模式的一個(gè)現(xiàn)代選擇。JSONP只支持GET請(qǐng)求,而CORS也支持其他類型的HTTP請(qǐng)求方法。使用CORS,開發(fā)者可以正常使用XMLHttpRequest對(duì)象發(fā)送請(qǐng)求,這種方法處理錯(cuò)誤比JSONP方便。從另一方面來說,JSONP可以兼容不支持CORS的老版瀏覽器。CORS只能被大多數(shù)現(xiàn)代瀏覽器支持。JSONP可能導(dǎo)致XSS問題,而CORS允許站點(diǎn)手動(dòng)解析響應(yīng)來確保安全。

做好前端開發(fā)必須對(duì)HTTP的相關(guān)知識(shí)有所了解,所以我創(chuàng)建了一個(gè)專題前端必備HTTP技能專門收集前端相關(guān)的HTTP知識(shí),歡迎關(guān)注,投稿。


PS:本文翻譯自維基百科,原文地址https://en.wikipedia.org/wiki/Cross-origin_resource_sharing

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容