同源策略和跨域

什么是跨域問題薛闪?

為什么會出現(xiàn)跨域問題?

因為瀏覽器的同源策略(同源指的是:協(xié)議+域名+端口相同)。

同源策略是瀏覽器的安全策略忠蝗,限制某一個域的網(wǎng)站或者網(wǎng)站加載的腳本如何與另一個域的資源進行交互。

也就是瀏覽器為了保護當(dāng)前的網(wǎng)站用戶的信息安全漓拾,限制了當(dāng)前網(wǎng)站與其他域的服務(wù)的交互阁最。所謂的限制并非阻止,而是通過一些約定好的方式骇两,決定是否進行這次跨域交互速种。

為什么瀏覽器要有同源策略

沒有同源策略限制的接口請求

先補充一個context:存儲在瀏覽器上的cookie會在瀏覽器向同一服務(wù)器再次發(fā)起請求時被自動攜帶,并發(fā)往server低千。

如果沒有同源策略的限制配阵,在下面這種csrf攻擊的情況下,你將會受到很大的影響

  • 你使用用戶名和密碼登錄了www.yinhang.com網(wǎng)站示血,并且獲取到了cookic并存放在了本地棋傍。
  • 之后給這個銀行server發(fā)送的www.yinhang.com/getMoney等請求都會自動的攜帶這個cookie作為用戶憑證給server發(fā)送請求
  • 突然你某一個地方誘導(dǎo)你點擊了一個壞網(wǎng)站 www.yinghangbad.com,這時候你點進去难审,這個網(wǎng)站偷偷的給銀行的server發(fā)送了請求www.yinhang.com/getMoney獲取你的賬戶信息瘫拣,顯而易見,這個請求和網(wǎng)站的域名并不相同告喊,如果沒有同源策略的限制麸拄,這個請求會被輕松的攜帶你的cookie從銀行server成功的獲取money信息

沒有同源策略限制的Dom查詢

某一個壞的網(wǎng)站利用<iframe>將銀行網(wǎng)站嵌入到自己的網(wǎng)站中,想要通過自己的寫的js文件黔姜,拿到嵌入的銀行網(wǎng)站的HTML username和password所在的input框的value拢切。

如果沒有瀏覽器的同源策略:只能access同源網(wǎng)站上的DOM元素, 那么壞網(wǎng)站上的JS就可以access銀行網(wǎng)站上的DOM元素秆吵,這將會造成用戶名和密碼泄露淮椰。


由此可見瀏覽器的同源策略確實能在某種程度上保護了你的網(wǎng)站。
同源策略導(dǎo)致了:

  • 非同源的請求無法通信,真實流程是:

    • 瀏覽器發(fā)現(xiàn)當(dāng)前的網(wǎng)站正在給一個非同源的服務(wù)發(fā)送請求主穗,瀏覽器在請求的header中加上一個Origin標識來自的源泻拦,幫助service判斷是否需要相應(yīng)來自這個域的請求
    • 當(dāng)請求的response回到瀏覽器,瀏覽器會首先檢查header中是否帶有Access-Control-Allow-Origin, 并且檢查該字段的value中是否包含當(dāng)前網(wǎng)站所在的域(也就是由server決定是否允許這個域的請求)黔牵,只有包含聪轿,瀏覽器才會將請求的response返回給網(wǎng)站。
  • 非同源的DOM或者JS無法訪問

  • 非同源的cookie猾浦、LocalStorage陆错、IndexDB無法讀寫

但是DOM的同源策略可以理解,對于網(wǎng)站上的所有請求總不能因為不同源而被全部阻斷金赦,那么如何允許跨域的請求呢音瓷?

會受到同源策略影響的資源

以下是會加載外部資源的HTML標簽:

  • script標簽對JS文件的請求
  • link標簽對css文件的請求
  • Img對image的請求
  • 通過 @font-face 引入的字體。一些瀏覽器允許跨域字體( cross-origin fonts)夹抗,一些需要同源字體(same-origin fonts)绳慎。
  • 通過 <video> 和 <audio> 播放的多媒體資源。
  • 通過 <object>漠烧、 <embed> 和 <applet> 嵌入的插件杏愤。
  • 通過 <iframe> 載入的任何資源。站點可以使用 X-Frame-Options 消息頭來阻止這種形式的跨域交互已脓。

會受到同源策略影響的資源

  • font
  • 所有ajax請求

在瀏覽器中, <script> 珊楼、<img>、<iframe>度液、<link>等標簽都可以跨域加載,而不受瀏覽器的同源策略的限制

如何解決因同源策略帶來的跨域請求失敗

一般我們都是采用CORS(跨域資源共享)解決此類問題的

跨域資源共享是一種基于HTTP header的機制厕宗。這個機制的原理:

  • 某一個ajax請求從一個網(wǎng)站發(fā)出,請求的server是一個和當(dāng)前網(wǎng)站域名不一致的server堕担,也就是說這是一個跨域請求已慢。

  • 請求剛開始被fire的時候,經(jīng)過瀏覽器霹购,瀏覽器檢測到這是一個跨域請求佑惠,就會自動在這個request的header中加上: Origin字段,value就是當(dāng)前網(wǎng)站protocol://host:port 比如https://developer.mozilla.org
    這個字段是不能夠被修改的

  • 請求到達Server之后厕鹃, 服務(wù)器可以檢查這個origin兢仰,并決定是否給這個origin提供服務(wù),提供怎樣的服務(wù)剂碴。

  • 如果服務(wù)器最終決定給這個請求提供服務(wù),那么服務(wù)器就需要讓瀏覽器知道轻专,因此需要在response header中帶上

Access-Control-Allow-Origin value中就是服務(wù)器能夠服務(wù)的域名

Access-Control-Allow-Origin: <origin> | *

注意這里的origin是能是一個域名不能是多個

  • 瀏覽器接受到來自response忆矛,會首先check header中是否包含Access-Control-Allow-Origin,并查看當(dāng)前的域是否在value中。如果是催训,瀏覽器會把response成功返回給網(wǎng)站洽议,如果不是,那么就會報錯漫拭。

ps: 當(dāng)然還包含很多其他的header亚兄,一般Access-Controll-XXX-XXX都是和跨域相關(guān)的header

當(dāng)然以上只是CORS的一種場景,正常情況根據(jù)請求的不同采驻,跨域機制也不同:

簡單請求

通常請求類型是:

  • GET
  • HEAD
  • POST

并且header中沒有特殊的內(nèi)容审胚,只有常見的accept、content-type等

且content-type只能是application/x-www-form-urlencoded text/plain

符合上述條件的請求一般就是簡單請求礼旅,簡單請求的跨域機制就符合上面的步驟膳叨,只要有origin以及access-controllXX

注意如果請求的header中content-type是application/json這類請求一定不是簡單請求。

非簡單請求(復(fù)雜請求)

較為復(fù)雜的不在上面簡單請求類型的請求就是復(fù)雜請求痘系,瀏覽器在發(fā)出這類請求之前會發(fā)出一個預(yù)檢請求

預(yù)檢請求
是當(dāng)你要發(fā)出一個跨域請求時菲嘴,瀏覽器會自動率先發(fā)出一個OPTION類型的請求,帶上Origin, 詢問服務(wù)器是否能夠允許接下來的實際復(fù)雜請求汰翠,預(yù)檢請求會在請求頭部帶上實際請求的相關(guān)信息:

Access-Control-Request-Method: POST
// 實際請求的method
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
// 實際請求中即將有的header

服務(wù)器會根據(jù)預(yù)檢請求帶來的實際請求的信息龄坪,決定是否允許接下來的實際請求,如果允許复唤,會在response的header中攜帶

Access-Control-Allow-Methods: GET, POST, PUT
// 必須字段健田,標明當(dāng)前服務(wù)器可以允許的來自此域的所有請求method
Access-Control-Allow-Headers: X-Custom-Header
// 標明當(dāng)前服務(wù)器可以允許的來自此域的所有請求能攜帶的header字段
Access-Control-Allow-Credentials: true
// 后續(xù)會提到
Access-Control-Max-Age: 1728000
// 可選字段,標明本次預(yù)檢請求的有效時間苟穆,在有效時間內(nèi)抄课,瀏覽器無須為同一請求再次發(fā)起預(yù)檢請求。請注意雳旅,瀏覽器自身維護了一個最大有效時間跟磨,如果該首部字段的值超過了最大有效時間,將不會生效攒盈。

瀏覽器會根據(jù)預(yù)檢請求的response決定是否發(fā)送實際請求給服務(wù)器抵拘。

之后的實際請求會按照上面簡單請求的流程,request會被瀏覽器攜帶origin, response必須有Access-Controll-Allow-XXX

帶credentials的請求

通常HTTP請求可以通過cookie 或者 Authorization header給服務(wù)器發(fā)送身份憑證型豁。

但是對于跨域的請求僵蛛,在沒有特殊設(shè)置的前提下,瀏覽器不會發(fā)送身份憑證信息給服務(wù)器迎变,也就是說任何cookie或者authorization都不會自動的攜帶到某一個請求上充尉。這是瀏覽器的同源策略之一。

那么如何將身份信息攜帶在請求中呢衣形?

需要雙重設(shè)置:

  • 需要在XMLHttpRequest或者fetch上設(shè)置
    request.withCredentials = true驼侠, 瀏覽器才會在請求上攜帶身份信息

  • 服務(wù)器接收到身份信息處理完畢之后姿鸿,必須在response中攜帶Access-Control-Allow-Credentials: true 否則瀏覽器不會把響應(yīng)內(nèi)容返回給請求的發(fā)送者。

  • 對于這種攜帶身份信息的請求倒源,它response的Access-Control-Allow-Origin 的value不能是*苛预,只能是origin

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市笋熬,隨后出現(xiàn)的幾起案子热某,更是在濱河造成了極大的恐慌,老刑警劉巖胳螟,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昔馋,死亡現(xiàn)場離奇詭異,居然都是意外死亡旺隙,警方通過查閱死者的電腦和手機绒极,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蔬捷,“玉大人垄提,你說我怎么就攤上這事≈芄眨” “怎么了铡俐?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長妥粟。 經(jīng)常有香客問我审丘,道長,這世上最難降的妖魔是什么勾给? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任滩报,我火速辦了婚禮,結(jié)果婚禮上播急,老公的妹妹穿的比我還像新娘脓钾。我一直安慰自己,他們只是感情好桩警,可當(dāng)我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布可训。 她就那樣靜靜地躺著,像睡著了一般捶枢。 火紅的嫁衣襯著肌膚如雪握截。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天烂叔,我揣著相機與錄音谨胞,去河邊找鬼。 笑死蒜鸡,一個胖子當(dāng)著我的面吹牛畜眨,可吹牛的內(nèi)容都是我干的昼牛。 我是一名探鬼主播术瓮,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼康聂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了胞四?” 一聲冷哼從身側(cè)響起恬汁,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎辜伟,沒想到半個月后氓侧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡导狡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年约巷,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旱捧。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡独郎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出枚赡,到底是詐尸還是另有隱情氓癌,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布贫橙,位于F島的核電站贪婉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏卢肃。R本人自食惡果不足惜疲迂,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望莫湘。 院中可真熱鬧尤蒿,春花似錦、人聲如沸逊脯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽军洼。三九已至巩螃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間匕争,已是汗流浹背避乏。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留甘桑,地道東北人拍皮。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓歹叮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親铆帽。 傳聞我的和親對象是個殘疾皇子咆耿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,092評論 2 355

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