跨域通信

一酪术、跨域and同源政策

1.跨域惩妇,指的是瀏覽器不能執(zhí)行其他網(wǎng)站的腳本普筹。它是由瀏覽器的同源策略造成的恤磷,是瀏覽器對(duì)javascript施加的安全限制面哼。
2.同源政策

  • 協(xié)議相同
  • 域名相同
  • 端口相同
    如:
    如,http://www.example.com/dir/page.html這個(gè)網(wǎng)址扫步,協(xié)議是http://魔策,域名是www.example.com,端口是80(默認(rèn)端口可以省略)河胎。它的同源情況如下闯袒。
    http://www.example.com/dir2/other.html:同源
    http://example.com/dir/other.html:不同源(域名不同)
    http://v2.www.example.com/dir/other.html:不同源(域名不同)
    http://www.example.com:81/dir/other.html:不同源(端口不同)
    https://www.example.com/dir/page.html:不同源(協(xié)議不同)

如果非同源,共有三種行為受到限制游岳。
(1) Cookie政敢、LocalStorage 和 IndexedDB 無法讀取。
(2) DOM 無法獲得胚迫。
(3) AJAX 請(qǐng)求無效(可以發(fā)送喷户,但瀏覽器會(huì)拒絕接受響應(yīng))。

二访锻、如何解決跨域問題

1.cookie

舉例來說褪尝,A網(wǎng)頁(yè)是http://w1.example.com/a.html,B網(wǎng)頁(yè)是http://w2.example.com/b.html期犬,那么只要設(shè)置相同的document.domain河哑,兩個(gè)網(wǎng)頁(yè)就可以共享Cookie。

document.domain = 'example.com';

這種方法只適用于 Cookieiframe窗口龟虎,LocalStorage 和 IndexedDB 無法通過這種方法璃谨,規(guī)避同源政策,而要使用PostMessage API鲤妥。

2. frame

如果兩個(gè)窗口一級(jí)域名相同佳吞,只是二級(jí)域名不同,那么設(shè)置document.domain屬性旭斥,就可以規(guī)避同源政策容达,拿到DOM古涧。

對(duì)于完全不同源的網(wǎng)站,目前有兩種方法,可以解決跨域窗口的通信問題捕透。

  • 片段識(shí)別符(fragment identifier)
    URL的#號(hào)后面的部分,比如http://example.com/x.html#fragment#fragment算芯。如果只是改變片段標(biāo)識(shí)符,頁(yè)面不會(huì)重新刷新凳宙。
    父窗口可以把信息熙揍,寫入子窗口的片段標(biāo)識(shí)符。
    子窗口通過監(jiān)聽hashchange事件得到通知氏涩。
    子窗口也可以改變父窗口的片段標(biāo)識(shí)符届囚。
  • 跨文檔通信API(Cross-document messaging)
    window.postMessage
    父窗口aaa.com向子窗口bbb.com發(fā)消息,調(diào)用postMessage是尖。
var popup = window.open('http://bbb.com', 'title');
popup.postMessage('Hello World!', 'http://bbb.com');

postMessage方法的第一個(gè)參數(shù)是具體的信息內(nèi)容意系,第二個(gè)參數(shù)是接收消息的窗口的源(origin),即“協(xié)議 + 域名 + 端口”饺汹。也可以設(shè)為*蛔添,表示不限制域名,向所有窗口發(fā)送兜辞。

子窗口向父窗口發(fā)送消息的寫法類似迎瞧。

window.opener.postMessage('Nice to see you', 'http://aaa.com');
  • message事件的事件對(duì)象event,提供以下三個(gè)屬性逸吵。
    event.source:發(fā)送消息的窗口
    event.origin: 消息發(fā)向的網(wǎng)址
    event.data: 消息內(nèi)容
window.addEventListener('message', receiveMessage);
function receiveMessage(event) {
  event.source.postMessage('Nice to see you!', '*');
}

3.LocalStorage

通過window.postMessage凶硅,讀寫其他窗口的 LocalStorage 也成為了可能。

3.AJAX

同源政策規(guī)定扫皱,AJAX請(qǐng)求只能發(fā)給同源的網(wǎng)址咏尝,否則就報(bào)錯(cuò)。
除了架設(shè)服務(wù)器代理(瀏覽器請(qǐng)求同源服務(wù)器啸罢,再由后者請(qǐng)求外部服務(wù))编检,有三種方法規(guī)避這個(gè)限制。

  • JSONP
  • WebSocket
  • CORS
    (1)JSONP是服務(wù)器與客戶端跨源通信的常用方法扰才。最大特點(diǎn)就是簡(jiǎn)單適用允懂,老式瀏覽器全部支持,服務(wù)器改造非常小衩匣。

它的基本思想是蕾总,網(wǎng)頁(yè)通過添加一個(gè)<script>元素,向服務(wù)器請(qǐng)求JSON數(shù)據(jù)琅捏,這種做法不受同源政策限制生百;服務(wù)器收到請(qǐng)求后,將數(shù)據(jù)放在一個(gè)指定名字的回調(diào)函數(shù)里傳回來柄延。

//網(wǎng)頁(yè)動(dòng)態(tài)插入<script>元素蚀浆,由它向跨源網(wǎng)址發(fā)出請(qǐng)求。
function addScriptTag(src) {
  var script = document.createElement('script');
  script.setAttribute("type","text/javascript");
  script.src = src;
  document.body.appendChild(script);
}
//向服務(wù)器example.com發(fā)出請(qǐng)求
window.onload = function () {
  addScriptTag('http://example.com/ip?callback=foo');
//該請(qǐng)求的查詢字符串有一個(gè)callback參數(shù),用來指定回調(diào)函數(shù)的名字市俊,這對(duì)于JSONP是必需的杨凑。
}

function foo(data) {
  console.log('Your public IP address is: ' + data.ip);
};
//服務(wù)器收到這個(gè)請(qǐng)求以后,會(huì)將數(shù)據(jù)放在回調(diào)函數(shù)的參數(shù)位置返回摆昧。
foo({
  "ip": "8.8.8.8"
});

(2)WebSocket是一種通信協(xié)議撩满,使用ws://(非加密)和wss://(加密)作為協(xié)議前綴。該協(xié)議不實(shí)行同源政策绅你,只要服務(wù)器支持伺帘,就可以通過它進(jìn)行跨源通信。

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

有一個(gè)字段是Origin忌锯,表示該請(qǐng)求的請(qǐng)求源(origin)曼追,即發(fā)自哪個(gè)域名。
正是因?yàn)橛辛薕rigin這個(gè)字段汉规,所以WebSocket才沒有實(shí)行同源政策礼殊。因?yàn)榉?wù)器可以根據(jù)這個(gè)字段,判斷是否許可本次通信针史。
(3)CORS

  • 跨源資源分享(Cross-Origin Resource Sharing)晶伦。相比JSONP只能發(fā)GET請(qǐng)求,CORS允許任何類型的請(qǐng)求啄枕。

  • 允許瀏覽器向跨源服務(wù)器婚陪,發(fā)出XMLHttpRequest請(qǐng)求,從而克服了AJAX只能同源使用的限制频祝。泌参。

  • CORS需要瀏覽器和服務(wù)器同時(shí)支持。目前常空,所有瀏覽器都支持該功能沽一,IE瀏覽器不能低于IE10。

  • 整個(gè)CORS通信過程漓糙,都是瀏覽器自動(dòng)完成

  • 兩種請(qǐng)求
    簡(jiǎn)單請(qǐng)求(simple request)

請(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

非簡(jiǎn)單請(qǐng)求(not-so-simple request)

請(qǐng)求方法
PUT
DELETE

或者Content-Type字段的類型是application/json昆禽。

  • CORS與JSONP的使用目的相同蝗蛙,但是比JSONP更強(qiáng)大。
    JSONP只支持GET請(qǐng)求醉鳖,CORS支持所有類型的HTTP請(qǐng)求捡硅。JSONP的優(yōu)勢(shì)在于支持老式瀏覽器,以及可以向不支持CORS的網(wǎng)站請(qǐng)求數(shù)據(jù)盗棵。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末壮韭,一起剝皮案震驚了整個(gè)濱河市北发,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌泰涂,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辐怕,死亡現(xiàn)場(chǎng)離奇詭異逼蒙,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)寄疏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門是牢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人陕截,你說我怎么就攤上這事驳棱。” “怎么了农曲?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵社搅,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我乳规,道長(zhǎng)形葬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任暮的,我火速辦了婚禮笙以,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘冻辩。我一直安慰自己猖腕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布恨闪。 她就那樣靜靜地躺著倘感,像睡著了一般。 火紅的嫁衣襯著肌膚如雪咙咽。 梳的紋絲不亂的頭發(fā)上侠仇,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音犁珠,去河邊找鬼逻炊。 笑死,一個(gè)胖子當(dāng)著我的面吹牛犁享,可吹牛的內(nèi)容都是我干的余素。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼炊昆,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼桨吊!你這毒婦竟也來了威根?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤视乐,失蹤者是張志新(化名)和其女友劉穎洛搀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體佑淀,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡留美,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了伸刃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谎砾。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖捧颅,靈堂內(nèi)的尸體忽然破棺而出景图,到底是詐尸還是另有隱情,我是刑警寧澤碉哑,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布挚币,位于F島的核電站,受9級(jí)特大地震影響扣典,放射性物質(zhì)發(fā)生泄漏忘晤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一激捏、第九天 我趴在偏房一處隱蔽的房頂上張望设塔。 院中可真熱鬧,春花似錦远舅、人聲如沸闰蛔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)序六。三九已至,卻和暖如春蚤吹,著一層夾襖步出監(jiān)牢的瞬間例诀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工裁着, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留繁涂,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓二驰,卻偏偏與公主長(zhǎng)得像扔罪,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子桶雀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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

  • 什么是同源策略 瀏覽器出于安全方面的考慮矿酵,只允許與本域下的接口交互唬复。不同源的客戶端腳本在沒有明確授權(quán)的情況下,不能...
    ezrealor閱讀 486評(píng)論 0 1
  • 歡迎關(guān)注微信公眾號(hào):全棧工廠 本文主要參考跨域資源共享 CORS 詳解[http://www.ruanyifeng...
    liqingbiubiu閱讀 1,824評(píng)論 0 3
  • 一全肮、瀏覽器的同源策略 1.什么是同源敞咧? 所謂“同源”指的是”三個(gè)相同“。相同的域名辜腺、端口和協(xié)議休建,這三個(gè)相同的話就視...
    徐國(guó)軍_plus閱讀 834評(píng)論 1 3
  • 跨域是什么 同源策略 在講解什么是跨域之前先要清楚什么是同源策略,“同源政策”(same-origin polic...
    JRG_Orange閱讀 953評(píng)論 0 52
  • 又吞下一塊高密度電餅后哪自,薛切切舒暢地打了個(gè)嗝丰包,渾身震動(dòng)禁熏,發(fā)出蜂鳴一樣的聲音壤巷。 “呃……開啟自檢模式∏票校”洶涌的電流在...
    黏在臉上的眼鏡閱讀 217評(píng)論 2 2