摘要:什么是跨域個(gè)人一句話解釋如果與不同源,那么頁(yè)面不能獲取頁(yè)面的資源。所以用同源策略來(lái)限制跨域是必須的。它是標(biāo)準(zhǔn),是跨源請(qǐng)求的根本解決方法。
本文整理了一些有關(guān)跨域的基礎(chǔ)知識(shí)和細(xì)節(jié)問(wèn)題。
什么是跨域個(gè)人一句話解釋:如果 url A 與 url B 不同源,那么頁(yè)面A不能獲取頁(yè)面B的資源。這里有兩個(gè)關(guān)鍵詞:url 和 同源,瀏覽器的同源策略就是針對(duì)兩個(gè)url,它們滿足以下三個(gè)條件,才是同源:
協(xié)議相同
域名相同
端口相同
https://www.baidu.com/
這里面有兩個(gè)細(xì)節(jié)需要提及,域名是包括//到/的所有部分www.baidu.com;沒(méi)有指定端口號(hào)默認(rèn)是:80端口。
如果一個(gè)頁(yè)面中的JS可以任意發(fā)起http跨域獲取其他頁(yè)面上的資源,這是一件很可怕的事,舉個(gè)例子:
張三訪問(wèn)了某銀行網(wǎng)站 abank.com,服務(wù)器端驗(yàn)證后會(huì)在響應(yīng)頭中加入Set-Cookie字段,然后下次張三再發(fā)起請(qǐng)求,瀏覽器會(huì)自動(dòng)將cookie附加在HTTP請(qǐng)求的首部字段Cookie中,服務(wù)器端就知道張三已經(jīng)登錄過(guò)了。
張三接著訪問(wèn)了危險(xiǎn)頁(yè)面 danger.com,這個(gè)頁(yè)面中寫(xiě)了一些Ajax,它發(fā)起請(qǐng)求訪問(wèn)abank.com,這一行為用戶不能察覺(jué),如果可以跨域發(fā)起請(qǐng)求,那么瀏覽器同樣會(huì)自動(dòng)將cookie附加在HTTP請(qǐng)求的首部字段Cookie中,這樣這個(gè)危險(xiǎn)危險(xiǎn)網(wǎng)站就登陸了張三的銀行賬戶。
所以用同源策略來(lái)限制跨域是必須的。
這里我思考了一個(gè)問(wèn)題,在瀏覽器地址欄里輸入url為什么沒(méi)有出現(xiàn)跨域問(wèn)題?
要明確,同源策略是瀏覽器的行為,在地址欄中輸入url是用戶主觀行為,所以瀏覽器是不判為跨域的。那么同源限制的對(duì)象其實(shí)是頁(yè)面中發(fā)起http請(qǐng)求的js。那同源限制的行為有哪些呢?有以下三種:
Cookie、LocalStorage 和 IndexDB 無(wú)法讀取。
DOM 無(wú)法獲得。
AJAX 請(qǐng)求不能發(fā)送。
接下來(lái)說(shuō)說(shuō)規(guī)避跨域限制的集中方式
針對(duì)AJAX的跨域 JSONPJSONP利用的的是:
上面的script標(biāo)簽向服務(wù)器example.com發(fā)出請(qǐng)求,該請(qǐng)求有一個(gè)查詢字符串callback參數(shù),用來(lái)指定回調(diào)函數(shù)的名字;服務(wù)器發(fā)現(xiàn)請(qǐng)求中有callback參數(shù),就會(huì)將JSON作為指定回調(diào)函數(shù)的參數(shù),回調(diào)函數(shù)作為腳本返回;腳本返回后,會(huì)直接作為代碼運(yùn)行,這時(shí),只要瀏覽器定義了foo函數(shù),該函數(shù)就會(huì)立即調(diào)用。
JSONP的缺點(diǎn)在于只能發(fā)GET請(qǐng)求。
CORSCORS是跨源資源分享(Cross-Origin Resource Sharing)的縮寫(xiě)。它是W3C標(biāo)準(zhǔn),是跨源AJAX請(qǐng)求的根本解決方法。相比JSONP只能發(fā)GET請(qǐng)求,CORS允許任何類型的請(qǐng)求。
CORS需要瀏覽器和服務(wù)器同時(shí)支持。目前,所有瀏覽器都支持該功能,IE瀏覽器不能低于IE10。
整個(gè)CORS通信過(guò)程,都是瀏覽器自動(dòng)完成,不需要用戶參與。對(duì)于開(kāi)發(fā)者來(lái)說(shuō),CORS通信與同源的AJAX通信沒(méi)有差別,代碼完全一樣。瀏覽器一旦發(fā)現(xiàn)AJAX請(qǐng)求跨源,就會(huì)自動(dòng)添加一些附加的頭信息,有時(shí)還會(huì)多出一次附加的請(qǐng)求,但用戶不會(huì)有感覺(jué)。
因此,實(shí)現(xiàn)CORS通信的關(guān)鍵是服務(wù)器。只要服務(wù)器實(shí)現(xiàn)了CORS接口,就可以跨源通信。
阮一峰老師關(guān)于CORS的文章非常細(xì)致,跨域資源共享 CORS 詳解,這里僅僅梳理下提綱備查。
瀏覽器將CORS請(qǐng)求分成兩類:簡(jiǎn)單請(qǐng)求(simple request)和非簡(jiǎn)單請(qǐng)求(not-so-simple request)。
只要同時(shí)滿足以下兩大條件,就屬于簡(jiǎn)單請(qǐng)求。
請(qǐng)求方法是以下三種方法之一:
HEAD
GET
POST
HTTP的頭信息不超出以下幾種字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三個(gè)值application/x-www-form-urlencoded、multipart/form-data、text/plain
凡是不同時(shí)滿足上面兩個(gè)條件,就屬于非簡(jiǎn)單請(qǐng)求。
簡(jiǎn)單請(qǐng)求簡(jiǎn)單請(qǐng)求的CORS分為以下幾步:
瀏覽器發(fā)現(xiàn)AJAX請(qǐng)求跨源,在請(qǐng)求頭中添加Origin字段,它的值是http請(qǐng)求的源url;
服務(wù)器根據(jù)Origin的值決定是否同意這次請(qǐng)求;
如果Origin指定的域名在服務(wù)器許可范圍內(nèi),則會(huì)在報(bào)頭中添加以下三個(gè)字段:
Access-Control-Allow-Origin
該字段是必須的。它的值要么是請(qǐng)求時(shí)Origin字段的值,要么是一個(gè)*,表示接受任意域名的請(qǐng)求.
Access-Control-Allow-Credentials
該字段可選。它的值是一個(gè)布爾值,表示是否允許發(fā)送Cookie。默認(rèn)情況下,Cookie不包括在CORS請(qǐng)求之中。設(shè)為true,即表示服務(wù)器明確許可,Cookie可以包含在請(qǐng)求中,一起發(fā)給服務(wù)器,另一方面,開(kāi)發(fā)者必須在AJAX請(qǐng)求中打開(kāi)withCredentials屬性。這個(gè)值也只能設(shè)為true,如果服務(wù)器不要瀏覽器發(fā)送Cookie,刪除該字段即可。
Access-Control-Expose-Headers
該字段可選。CORS請(qǐng)求時(shí),XMLHttpRequest對(duì)象的getResponseHeader()方法只能拿到6個(gè)基本字段。
如果如果Origin指定的域名不在服務(wù)器許可范圍內(nèi),響應(yīng)頭中沒(méi)有Access-Control-Allow-Origin,瀏覽器就會(huì)拋出錯(cuò)誤,中斷這個(gè)http請(qǐng)求。
非簡(jiǎn)單請(qǐng)求簡(jiǎn)單請(qǐng)求的CORS分為以下幾步:
瀏覽器在正式請(qǐng)求之前,先發(fā)送一個(gè)預(yù)檢請(qǐng)求,預(yù)檢請(qǐng)求的請(qǐng)求方法是OPTIONS,請(qǐng)求頭中帶以下三個(gè)字段:
Access-Control-Request-Method
該字段是必須的,用來(lái)列出瀏覽器的CORS請(qǐng)求會(huì)用到哪些HTTP方法
Access-Control-Request-Headers
可選,該字段是一個(gè)逗號(hào)分隔的字符串,指定瀏覽器CORS請(qǐng)求會(huì)額外發(fā)送的頭信息字段
如果服務(wù)器端預(yù)檢不通過(guò),瀏覽器報(bào)錯(cuò);如果通過(guò),返回的響應(yīng)頭中包含以下幾個(gè)字段:
Access-Control-Allow-Origin
一定包含
Access-Control-Allow-Methods
一定包含,它的值是逗號(hào)分隔的一個(gè)字符串,表明服務(wù)器支持的所有跨域請(qǐng)求的方法。
Access-Control-Allow-Credentials
可選
Access-Control-Max-Age
可選,用來(lái)指定本次預(yù)檢請(qǐng)求的有效期,單位為秒,未過(guò)期的話不用再發(fā)送預(yù)檢請(qǐng)求。
一旦服務(wù)器通過(guò)了"預(yù)檢"請(qǐng)求,以后每次瀏覽器正常的CORS請(qǐng)求,就都跟簡(jiǎn)單請(qǐng)求一樣,會(huì)有一個(gè)Origin頭信息字段。服務(wù)器的回應(yīng),也都會(huì)有一個(gè)Access-Control-Allow-Origin頭信息字段。
WebSocketWebSocket是一種通信協(xié)議,使用ws://(非加密)和wss://(加密)作為協(xié)議前綴。該協(xié)議不實(shí)行同源政策,只要服務(wù)器支持,就可以通過(guò)它進(jìn)行跨源通信。
針對(duì)CookieCookie 是服務(wù)器寫(xiě)入瀏覽器的一小段信息,只有同源的網(wǎng)頁(yè)才能共享。但是,兩個(gè)網(wǎng)頁(yè)一級(jí)域名相同,只是二級(jí)域名不同,瀏覽器允許通過(guò)設(shè)置document.domain共享 Cookie。
舉例來(lái)說(shuō),A網(wǎng)頁(yè)是http://w1.example.com/a.html,B網(wǎng)頁(yè)是http://w2.example.com/b.html,那么只要在兩個(gè)網(wǎng)頁(yè)的腳本中設(shè)置的document.domain="example.com",兩個(gè)網(wǎng)頁(yè)就可以共享Cookie。
針對(duì)iframe如果兩個(gè)網(wǎng)頁(yè)不同源,就無(wú)法拿到對(duì)方的DOM。典型的例子是iframe窗口和window.open方法打開(kāi)的窗口,它們與父窗口無(wú)法通信。對(duì)于完全不同源的網(wǎng)站,目前有三種方法,可以解決跨域窗口的通信問(wèn)題:
片段識(shí)別符(fragment identifier)
window.name
跨文檔通信API(Cross-document messaging),HTML5中的window.postMessage
參考文章:
瀏覽器同源政策及其規(guī)避方法
跨域資源共享 CORS 詳解
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/96483.html
摘要:學(xué)習(xí)建議在學(xué)習(xí)其中一種跨域方法的時(shí)候,建議邊運(yùn)行項(xiàng)目里的,邊在網(wǎng)上搜索博客文章學(xué)習(xí)這種跨域方法,這樣有助于快速并且深入理解跨域。鑒于網(wǎng)上有很多文章詳細(xì)講述跨域知識(shí),只是少了可以本地運(yùn)行的,所以這里就不再贅述跨域知識(shí)。 前言 因?yàn)閷W(xué)習(xí)跨域需要配置本地服務(wù)器,可能會(huì)比較麻煩,所以自己根據(jù)網(wǎng)上的博客寫(xiě)了大多數(shù)跨域的簡(jiǎn)單demo,可以自己在本地運(yùn)行,而且不用配置服務(wù)器。自己對(duì)于跨域的理解剛開(kāi)始...
摘要:學(xué)習(xí)建議在學(xué)習(xí)其中一種跨域方法的時(shí)候,建議邊運(yùn)行項(xiàng)目里的,邊在網(wǎng)上搜索博客文章學(xué)習(xí)這種跨域方法,這樣有助于快速并且深入理解跨域。鑒于網(wǎng)上有很多文章詳細(xì)講述跨域知識(shí),只是少了可以本地運(yùn)行的,所以這里就不再贅述跨域知識(shí)。 前言 因?yàn)閷W(xué)習(xí)跨域需要配置本地服務(wù)器,可能會(huì)比較麻煩,所以自己根據(jù)網(wǎng)上的博客寫(xiě)了大多數(shù)跨域的簡(jiǎn)單demo,可以自己在本地運(yùn)行,而且不用配置服務(wù)器。自己對(duì)于跨域的理解剛開(kāi)始...
摘要:學(xué)習(xí)建議在學(xué)習(xí)其中一種跨域方法的時(shí)候,建議邊運(yùn)行項(xiàng)目里的,邊在網(wǎng)上搜索博客文章學(xué)習(xí)這種跨域方法,這樣有助于快速并且深入理解跨域。鑒于網(wǎng)上有很多文章詳細(xì)講述跨域知識(shí),只是少了可以本地運(yùn)行的,所以這里就不再贅述跨域知識(shí)。 前言 因?yàn)閷W(xué)習(xí)跨域需要配置本地服務(wù)器,可能會(huì)比較麻煩,所以自己根據(jù)網(wǎng)上的博客寫(xiě)了大多數(shù)跨域的簡(jiǎn)單demo,可以自己在本地運(yùn)行,而且不用配置服務(wù)器。自己對(duì)于跨域的理解剛開(kāi)始...
摘要:說(shuō)明關(guān)于跨域問(wèn)題的解決方案多達(dá)七八種,你不要說(shuō)哪有這么多,我不跟你較真哈,你也別跟我較真哈自行百度或這里不會(huì)跟你說(shuō)那么多種只說(shuō)使用最多的一種你要非說(shuō)用的不是最多的我不信哦你信好了哈哈你開(kāi)心就好關(guān)于跨域?yàn)g覽器的同源策略要了解什么是跨域你需要了 說(shuō)明 關(guān)于跨域問(wèn)題的解決方案多達(dá)七、八種,你不要說(shuō)哪有這么多,我不跟你較真哈,你也別跟我較真哈, ?!自行 百度 或 Google, 這里不會(huì)跟你...
摘要:跨域跨域產(chǎn)生原因協(xié)議名不一樣主機(jī)不一樣端口不一樣跨域有無(wú)問(wèn)題請(qǐng)求會(huì)產(chǎn)生問(wèn)題這是瀏覽器處理的結(jié)果通過(guò)統(tǒng)一資源定位獲取的圖片資源也是一種跨域但是不會(huì)產(chǎn)生問(wèn)題處理跨域的方法只支持返回響應(yīng)頭允許跨域開(kāi)發(fā)中使用服務(wù)器代理例如一服務(wù)器端設(shè)置響 web跨域 跨域產(chǎn)生原因: a. 協(xié)議名不一樣 b. 主機(jī)不一樣 c. 端口不一樣 跨域有無(wú)問(wèn)題: a. ajax請(qǐng)求會(huì)產(chǎn)生問(wèn)題, 這...
閱讀 3398·2023-04-25 22:04
閱讀 2197·2021-11-22 15:29
閱讀 2161·2021-10-11 10:57
閱讀 1402·2021-09-24 09:48
閱讀 3147·2021-09-09 09:34
閱讀 2543·2021-09-02 15:21
閱讀 2393·2019-08-30 15:53
閱讀 1120·2019-08-30 14:07