兩個瀏覽器窗口間通信總結(jié)


1姨拥、localStorage

一個窗口更新localStorage绅喉,另一個窗口監(jiān)聽window對象的”storage”事件,來實(shí)現(xiàn)通信叫乌。
注:兩個頁面要同源(URL的協(xié)議柴罐、域名和端口相同)

  1. // 本窗口的設(shè)值代碼

  2. localStorage.setItem('aaa', (Math.random()*10).toString())


  3. // 其他窗口監(jiān)聽storage事件

  4. window.addEventListener("storage", function (e) {

  5. ?console.log(e)

  6. ?console.log(e.newValue)

  7. })

2、WebSocket

所有的WebSocket都監(jiān)聽同一個服務(wù)器地址憨奸,利用send發(fā)送消息革屠,利用onmessage獲取消息的變化,不僅能窗口排宰,還能跨瀏覽器似芝,兼容性最佳,只是需要消耗點(diǎn)服務(wù)器資源板甘。

  1. var ws = new WebSocket("ws://localhost:3000/")

  2. ws.onopen = function (event) {

  3. ?// 或者把此方法注冊到其他事件中党瓮,即可與其他服務(wù)器通信

  4. ?ws.send({now : Date.now()}); // 通過服務(wù)器中轉(zhuǎn)消息

  5. };

  6. ws.onmessage = function (event) {

  7. ?// 消費(fèi)消息

  8. ?console.log(event.data);

  9. }

3、postMessage

借助iframe 或 window.open
回顧一下API

  1. otherWindow.postMessage(message, targetOrigin, [transfer]);

  • otherWindow
    其他窗口的一個引用盐类,比如iframe的contentWindow屬性寞奸、執(zhí)行window.open返回的窗口對象呛谜、或者是命名過或數(shù)值索引的window.frames。

  • message
    將要發(fā)送到其他 window的數(shù)據(jù)枪萄。它將會被結(jié)構(gòu)化克隆算法序列化隐岛。這意味著你可以不受什么限制的將數(shù)據(jù)對象安全的傳送給目標(biāo)窗口而無需自己序列化。

  • targetOrigin
    通過窗口的origin屬性來指定哪些窗口能接收到消息事件瓷翻,其值可以是字符串""(表示無限制)或者一個URI聚凹。在發(fā)送消息的時候,如果目標(biāo)窗口的協(xié)議齐帚、主機(jī)地址或端口這三者的任意一項(xiàng)不匹配targetOrigin提供的值妒牙,那么消息就不會被發(fā)送;只有三者完全匹配童谒,消息才會被發(fā)送。這個機(jī)制用來控制消息可以發(fā)送到哪些窗口沪羔;例如饥伊,當(dāng)用postMessage傳送密碼時,這個參數(shù)就顯得尤為重要蔫饰,必須保證它的值與這條包含密碼的信息的預(yù)期接受者的origin屬性完全一致琅豆,來防止密碼被惡意的第三方截獲。如果你明確的知道消息應(yīng)該發(fā)送到哪個窗口篓吁,那么請始終提供一個有確切值的targetOrigin茫因,而不是。不提供確切的目標(biāo)將導(dǎo)致數(shù)據(jù)泄露到任何對數(shù)據(jù)感興趣的惡意站點(diǎn)杖剪。

  • transfer 可選
    是一串和message 同時傳遞的 Transferable 對象. 這些對象的所有權(quán)將被轉(zhuǎn)移給消息的接收方冻押,而發(fā)送一方將不再保有所有權(quán)。


    1. /*

    2. * A窗口的域名是<http://example.com:8080>盛嘿,以下是A窗口的script標(biāo)簽下的代碼:

    3. */


    4. var popup = window.open(...popup details...);


    5. // 如果彈出框沒有被阻止且加載完成


    6. // 這行語句沒有發(fā)送信息出去洛巢,即使假設(shè)當(dāng)前頁面沒有改變location(因?yàn)閠argetOrigin設(shè)置不對)

    7. popup.postMessage("The user is 'bob' and the password is 'secret'",

    8. ? ? ? ? ? ? ? ? ?"https://secure.example.net");


    9. // 假設(shè)當(dāng)前頁面沒有改變location,這條語句會成功添加message到發(fā)送隊列中去(targetOrigin設(shè)置對了)

    10. popup.postMessage("hello there!", "http://example.org");


    11. function receiveMessage(event)

    12. {

    13. ?// 我們能相信信息的發(fā)送者嗎? ?(也許這個發(fā)送者和我們最初打開的不是同一個頁面).

    14. ?if (event.origin !== "http://example.org")

    15. ? ?return;


    16. ?// event.source 是我們通過window.open打開的彈出頁面 popup

    17. ?// event.data 是 popup發(fā)送給當(dāng)前頁面的消息 "hi there yourself! ?the secret response is: rheeeeet!"

    18. }

    19. window.addEventListener("message", receiveMessage, false);



    20. /*

    21. * 彈出頁 popup 域名是<http://example.org>次兆,以下是script標(biāo)簽中的代碼:

    22. */


    23. //當(dāng)A頁面postMessage被調(diào)用后稿茉,這個function被addEventListenner調(diào)用

    24. function receiveMessage(event)

    25. {

    26. ?// 我們能信任信息來源嗎?

    27. ?if (event.origin !== "http://example.com:8080")

    28. ? ?return;


    29. ?// event.source 就當(dāng)前彈出頁的來源頁面

    30. ?// event.data 是 "hello there!"


    31. ?// 假設(shè)你已經(jīng)驗(yàn)證了所收到信息的origin (任何時候你都應(yīng)該這樣做), 一個很方便的方式就是把enent.source

    32. ?// 作為回信的對象芥炭,并且把event.origin作為targetOrigin

    33. ?event.source.postMessage("hi there yourself! ?the secret response " +

    34. ? ? ? ? ? ? ? ? ? ? ? ? ? "is: rheeeeet!",

    35. ? ? ? ? ? ? ? ? ? ? ? ? ? event.origin);

    36. }


    37. window.addEventListener("message", receiveMessage, false);

    4漓库、cookie + setInterval【差】

    在頁面A設(shè)置一個使用 setInterval 定時器不斷刷新,檢查 Cookies 的值是否發(fā)生變化园蝠,如果變化就進(jìn)行刷新的操作渺蒿。

    由于 Cookies 是在同域可讀的,所以在頁面 B 審核的時候改變 Cookies 的值彪薛,頁面 A 自然是可以拿到的蘸嘶。

    這樣做確實(shí)可以實(shí)現(xiàn)我想要的功能良瞧,但是這樣的方法相當(dāng)浪費(fèi)資源。雖然在這個性能過盛的時代训唱,浪費(fèi)不浪費(fèi)也感覺不出來褥蚯,但是這種實(shí)現(xiàn)方案,確實(shí)不夠優(yōu)雅况增。

    5赞庶、SharedWorker

    HTML5 中的 Web Worker 可以分為兩種不同線程類型,一個是專用線程 Dedicated Worker澳骤,一個是共享線程 Shared Worker歧强。

  • Dedicated Worker直接使用new Worker()即可創(chuàng)建,這種webworker是當(dāng)前頁面專有的为肮。摊册。

  • SharedWorker可以被多個window、標(biāo)簽頁颊艳、iframe共同使用茅特,但必須保證這些標(biāo)簽頁都是同源的(相同的協(xié)議,主機(jī)和端口號)


  • 6棋枕、直接引用

    其實(shí)就是直接獲取對方DOM白修,適用于兩個頁面在同一域;可以傳遞對象數(shù)據(jù)(對象數(shù)據(jù)使用 instanceof 做類型判斷時有坑)重斑;參考 window.open兵睛;
    例:

    1. // 父頁面獲取子iframe

    2. document.getElementById('iframe的id').contentWindow.document


    3. // 子iframe獲取父頁面

    4. window.parent.document

    7、window.name

    瀏覽器窗口有window.name屬性窥浪。這個屬性的最大特點(diǎn)是祖很,無論是否同源,只要在同一個窗口里漾脂,前一個網(wǎng)頁設(shè)置了這個屬性突琳,后一個網(wǎng)頁可以讀取它。

    父窗口先打開一個子窗口符相,載入一個不同源的網(wǎng)頁拆融,該網(wǎng)頁將信息寫入window.name屬性。

    1. window.name = data;

    接著啊终,子窗口跳回一個與主窗口同域的網(wǎng)址镜豹。

    1. window.location.;

    然后,主窗口就可以讀取子窗口的window.name了蓝牲。

    1. var data = document.getElementById('iframe的id').contentWindow.name;

    這種方法的優(yōu)點(diǎn)是趟脂,window.name容量很大,可以放置非常長的字符串例衍;缺點(diǎn)是必須監(jiān)聽子窗口window.name屬性的變化昔期,影響網(wǎng)頁性能已卸。


    源自:https://segmentfault.com/a/1190000016927268

    聲明:文章著作權(quán)歸作者所有,如有侵權(quán)硼一,請聯(lián)系小編刪除累澡。

    ?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
    • 序言:七十年代末,一起剝皮案震驚了整個濱河市般贼,隨后出現(xiàn)的幾起案子愧哟,更是在濱河造成了極大的恐慌,老刑警劉巖哼蛆,帶你破解...
      沈念sama閱讀 221,820評論 6 515
    • 序言:濱河連續(xù)發(fā)生了三起死亡事件蕊梧,死亡現(xiàn)場離奇詭異,居然都是意外死亡腮介,警方通過查閱死者的電腦和手機(jī)肥矢,發(fā)現(xiàn)死者居然都...
      沈念sama閱讀 94,648評論 3 399
    • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叠洗,“玉大人甘改,你說我怎么就攤上這事√栉叮” “怎么了楼誓?”我有些...
      開封第一講書人閱讀 168,324評論 0 360
    • 文/不壞的土叔 我叫張陵玉锌,是天一觀的道長名挥。 經(jīng)常有香客問我,道長主守,這世上最難降的妖魔是什么禀倔? 我笑而不...
      開封第一講書人閱讀 59,714評論 1 297
    • 正文 為了忘掉前任,我火速辦了婚禮参淫,結(jié)果婚禮上救湖,老公的妹妹穿的比我還像新娘。我一直安慰自己涎才,他們只是感情好鞋既,可當(dāng)我...
      茶點(diǎn)故事閱讀 68,724評論 6 397
    • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著耍铜,像睡著了一般邑闺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上棕兼,一...
      開封第一講書人閱讀 52,328評論 1 310
    • 那天陡舅,我揣著相機(jī)與錄音,去河邊找鬼伴挚。 笑死靶衍,一個胖子當(dāng)著我的面吹牛灾炭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播颅眶,決...
      沈念sama閱讀 40,897評論 3 421
    • 文/蒼蘭香墨 我猛地睜開眼蜈出,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了帚呼?” 一聲冷哼從身側(cè)響起掏缎,我...
      開封第一講書人閱讀 39,804評論 0 276
    • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎煤杀,沒想到半個月后眷蜈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
      沈念sama閱讀 46,345評論 1 318
    • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沈自,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
      茶點(diǎn)故事閱讀 38,431評論 3 340
    • 正文 我和宋清朗相戀三年酌儒,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枯途。...
      茶點(diǎn)故事閱讀 40,561評論 1 352
    • 序言:一個原本活蹦亂跳的男人離奇死亡忌怎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酪夷,到底是詐尸還是另有隱情榴啸,我是刑警寧澤,帶...
      沈念sama閱讀 36,238評論 5 350
    • 正文 年R本政府宣布晚岭,位于F島的核電站鸥印,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏坦报。R本人自食惡果不足惜库说,卻給世界環(huán)境...
      茶點(diǎn)故事閱讀 41,928評論 3 334
    • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望片择。 院中可真熱鬧潜的,春花似錦、人聲如沸字管。這莊子的主人今日做“春日...
      開封第一講書人閱讀 32,417評論 0 24
    • 文/蒼蘭香墨 我抬頭看了看天上的太陽嘲叔。三九已至亡呵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間借跪,已是汗流浹背政己。 一陣腳步聲響...
      開封第一講書人閱讀 33,528評論 1 272
    • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人歇由。 一個月前我還...
      沈念sama閱讀 48,983評論 3 376
    • 正文 我出身青樓卵牍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親沦泌。 傳聞我的和親對象是個殘疾皇子糊昙,可洞房花燭夜當(dāng)晚...
      茶點(diǎn)故事閱讀 45,573評論 2 359