same origin policy & CORS --- 同源策略 與 跨域資源共享

跨域?qū)τ谇岸藖碇v是個耳熟的字眼,在日常工作和面試中經(jīng)常出現(xiàn)谒臼。
本文介紹了同源策略耀里、CORS跨域資源共享實際開發(fā)中如何處理跨域這幾個方面底哥。

前端開發(fā)過程中房官,你肯定見過這個報錯趾徽。Access to fetch at 'https://m.demo.com' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. 這就是跨域請求被瀏覽器攔截沒跑了孵奶。

same origin policy & CORS

同源策略 (same origin policy)蜡峰,是瀏覽器最核心、最基本的安全功能之一事示。它限制了從一個源(origin)加載的文檔如何與另外一個源的資源進行交互。
Web應(yīng)用程序只能從加載應(yīng)用程序的同一個域請求HTTP資源卢鹦,除非響應(yīng)報文包含了正確CORS響應(yīng)頭劝堪。
更詳細(xì)的說,是瀏覽器對在腳本內(nèi)跨源發(fā)起的 http請求 的response結(jié)果進行了攔截秒啦。
想象一下,如果沒有這個策略限制驻呐,就會發(fā)生某一個源隨意調(diào)用其他源的接口獲取他人數(shù)據(jù),篡改他們數(shù)據(jù)……等等肥腸價值觀警告的事情含末。

該策略常見的三種情況:

  • Cross-origin writes 跨域?qū)?/strong> 例如鏈接links、重定向挎袜、表單提交……
  • Cross-origin embedding 資源嵌入 比如 script 肥惭、link、img蜜葱、video等標(biāo)簽嵌入資源
  • Cross-origin reads 跨域讀 但可通過嵌入巧妙繞過

同源就是指兩個頁面的協(xié)議、主機笼沥、端口號(如果有)三者皆一致娶牌。 當(dāng)一個資源a從一個與該資源a所在服務(wù)器a不同協(xié)議、域或端口 的服務(wù)器b上請求另一個資源b汹桦,這就發(fā)起了一個跨域HTTP請求鉴裹。

exp:http:/ / www. baidu. com:80 http即協(xié)議,www. baidu . com即主機径荔,80即端口號。

但有時候開發(fā)中狈惫,確實存在這樣鹦马、那樣的跨域資源獲取需求。這就要講到跨域資源共享(Cross-Origin Resource Sharing) 荸频,允許服務(wù)器聲明 哪些 有權(quán)限通過瀏覽器 訪問哪些資源。給我們爭取一個跨域請求的機會稳强。
借用個栗子,客戶端發(fā)起一個simple request get請求:

image

  • Client request header請求頭 get 請求獲取 /resources/public-data/ 下的資源
GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/\*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http:\/\/foo.example\/examples\/access-control\/simpleXSInvocation.html
Origin: http:\/\/foo.example
  • Server response header 響應(yīng)頭
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.0.61 
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

[XML Data]

服務(wù)端返回的 Access-Control-Allow-Origin: *表明燎窘,該資源可被任意外域訪問蹄咖。
ps:如果服務(wù)器僅希望某個源(比如http:/ /examples.com)可以訪問其資源,只需設(shè)置 Access-Control-Allow-Origin: http:/ /examples.com 蚜迅。如果希望僅允許GET請求或多種請求俊抵,則可設(shè)置 Access-Control-Allow-Methods:GET, POST, ……

解決方法

已知的一些方法在生產(chǎn)環(huán)境幾乎都需要server進行配合徽诲,本地開發(fā)的話前端是完全可以自行繞過跨源問題。

方法如下(前四種適用于生產(chǎn)環(huán)境):
1偷溺、后端在reponse header中添加 Access-Control-Allow-Origin: xxx允許跨源請求钱贯。

exp,http: //hello-world.example 想訪問 http: //example.com 的資源秩命。 http: //example.com 在response header 中添加 Access-Control-Allow-Origin: http: //hello-world.example
當(dāng)然 也可以一了百了添加 Access-Control-Allow-Origin: * 弃锐,只要你確保不會產(chǎn)生其他副作用。

2剧蚣、前端使用JSONP浇辜。

像一些資源標(biāo)簽(如img,video柳洋,script……)允許跨源資源嵌入,即標(biāo)簽的src是允許嵌入跨源資源的卑雁。jsonp其實就是通過 script src 傳遞參數(shù)(請求參數(shù)、約定的callback name)給服務(wù)器测蹲,服務(wù)器將返回數(shù)據(jù)包裹在回調(diào)函數(shù)中,直接在腳本中進行調(diào)用達(dá)到跨域獲取資源數(shù)據(jù)的效果篮赢。

3琉挖、document.domain,允許子域安全訪問其父域示辈。

document.domain 的值可以設(shè)置為其當(dāng)前域或其當(dāng)前域的父域。如果將其設(shè)置為其當(dāng)前域的父域纱耻,則這個較短的父域?qū)⒂糜诤罄m(xù)源檢查险耀。(設(shè)置后當(dāng)前域端口號會被重寫為Null)
舉個栗子胰耗,假設(shè)http: //demo.example.com中有一個腳本執(zhí)行了 document.domain = 'example.com'; 那么瀏覽器將會通過對http: //company.com/dir/page.html (http: //company.com/dir/page.html 也必須設(shè)置document.domain = 'example.com'; 以重置端口號)資源的同源檢測柴灯。

4费尽、OPTIONS預(yù)檢請求

preflight request 是一個包含了:Access-Control-Request-MethodAccess-Control-Request-Headers,以及一個 Origin 首部的options請求旱幼。服務(wù)器基于從預(yù)檢請求獲得的信息來判斷,是否接受接下來的實際請求冬三。
對于可能對服務(wù)器數(shù)據(jù)產(chǎn)生副作用的請求(GET以外缘缚,搭配某些MIME type的請求),瀏覽器都會先發(fā)出一個預(yù)檢請求桥滨,以監(jiān)測服務(wù)器是否允許該類型的請求弛车。確認(rèn)允許后蒲每,才會發(fā)出實際請求。
OPTIONS 請求用于獲取目的資源所支持的通信選項贫奠。

5望蜡、如果是本地開發(fā),還可使用chrome - Allow CORS: Access-Control-Allow-origin插件允許跨域浩姥,或命令行 open -a "Google Chrome" --args --disable-web-security --user-data-dir 状您。

chrome插件的做法應(yīng)該就是在 response 達(dá)到瀏覽器前,在 response header 中添加了 Access-Control-Allow-Origin 和 Access-Control-Allow-Methods 兩個字段來達(dá)到允許跨域資源共享的原理膏孟。

6、webpack proxy可以在開發(fā)環(huán)境代理跨域請求弊决,但build打包后魁淳,代理是不生效的,請注意這點界逛。

參考資料

CORS:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
瀏覽器同源策略:https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy
Document.domain:https://developer.mozilla.org/zh-CN/docs/Web/API/Document/domain
W3C Cross-Origin Resource Sharing:https://www.w3.org/TR/cors/

如有遺漏的方法 歡迎補充討論 ~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末息拜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子少欺,更是在濱河造成了極大的恐慌,老刑警劉巖畏陕,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件氯庆,死亡現(xiàn)場離奇詭異扰付,居然都是意外死亡仁讨,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門盐固,熙熙樓的掌柜王于貴愁眉苦臉地迎上來丈挟,“玉大人,你說我怎么就攤上這事蛔趴±欤” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵箫荡,是天一觀的道長渔隶。 經(jīng)常有香客問我,道長间唉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任镀赌,我火速辦了婚禮际跪,結(jié)果婚禮上喉钢,老公的妹妹穿的比我還像新娘。我一直安慰自己肠虽,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布闲延。 她就那樣靜靜地躺著,像睡著了一般陆馁。 火紅的嫁衣襯著肌膚如雪合愈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天益老,我揣著相機與錄音寸莫,去河邊找鬼。 笑死膘茎,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的慈参。 我是一名探鬼主播刮萌,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼壮锻!你這毒婦竟也來了涮阔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤敬特,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后辣之,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體皱炉,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年多搀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片廊谓。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡麻削,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出呛哟,到底是詐尸還是另有隱情,我是刑警寧澤榛鼎,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布鳖孤,位于F島的核電站,受9級特大地震影響苏揣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜框沟,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一增炭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧梅垄,春花似錦输玷、人聲如沸队丝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽裙犹。三九已至尽狠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間践图,已是汗流浹背沉馆。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留斥黑,地道東北人。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓兽狭,卻偏偏與公主長得像鹿蜀,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子茴恰,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容