vue+webpack+postMessage+iframe雙標(biāo)簽頁通信

  • 本文記錄一下工作中關(guān)于雙標(biāo)簽頁通信問題
  • 涉及的技術(shù):vue webpack postMessage iframe
  • 如今網(wǎng)上已經(jīng)有許多關(guān)于多標(biāo)簽頁通信技術(shù)文檔,但終究不是十分適用自己的需求,所以實踐出真知,我來總結(jié)一下自己的經(jīng)驗

  1. 了解一下postMessage:MDN-postMessage
    主要是下面2個API
  • onmessage
window.onmessage = e =>{
  console.log(e.data) //接收到的信息在e.data里
}
  • postMessage
window.postMessage({event:'changePoroject',data:{name:'小強'}},location.origin)

注意點說明:
1.window-指的是需要傳遞消息頁面的引用
2.傳遞的第二個參數(shù)官方說明是-可以接收消息的頁面(一般指url)

  1. iframe
<iframe src='baidu.com' ref='iframe1' id='iframe><iframe>

獲取iframewindow對象

  • vue
this.$refs.iframe1.contentWindow
  • iframe內(nèi)外傳遞信息也是通過postmesagepostMessage
  1. 下面來聊一下兩個Tab頁通信的實現(xiàn)方式和注意點
  • 約定數(shù)據(jù)格式-也就是mesasge選項的格式
{event:'changePoroject',data:{name:'小強'}}

event為我要傳遞的事件,data我要傳遞的參數(shù),這樣就能像監(jiān)聽事件一樣來交互

  • onmessage監(jiān)聽事件-放在mountedcreated
  • window.open打開子頁面
    1. 子頁面初始化(包括初次打開和頁面刷新)時,向父頁面發(fā)送請求,初始化數(shù)據(jù);監(jiān)聽子頁面onload事件初始化數(shù)據(jù),有時間上的誤差,不能及時初始化子頁面數(shù)據(jù),所以要在mountedcreated里向父頁面發(fā)送初始化請求
    2. 父頁面點擊關(guān)閉和刷新頁面時,子頁面引用對象調(diào)用close方法,childPage.close()
    3. 監(jiān)聽子頁面關(guān)閉,循環(huán)監(jiān)聽子頁面closed值,為true則改變父頁面的相關(guān)狀態(tài)
    4. 子頁面監(jiān)聽父頁面的刷新狀態(tài),如果父頁面刷新-關(guān)閉自己-window.close()
    5. 在子頁面里-window.opener代表了父頁面,可以使用window.opener.postMessage來向父頁面發(fā)送消息
  • webpack
    初始化時,onmessage會監(jiān)聽到webpack發(fā)送的請求,所以接收到數(shù)據(jù)后要先判斷數(shù)據(jù)格式,然后再進行操作

下面是兩個頁面交互的部分代碼

//打開分屏頁面
this.childPage = window.open(this.secondUrl,‘child’)
let loop = setInterval(()=>{
  if(this.childPage.closed){
   clearInterval(loop) 
    .... //監(jiān)聽子頁面關(guān)閉,父頁面做出相應(yīng)的改動
  }  
},1000)
//主頁面
mounted(){
 window.onmessage = e => {
  if(typeof e.data === 'string'){
   console.log('傳遞無效信息')
 }else {
  if(e.data.event){
    console.log('正常發(fā)送數(shù)據(jù)')
    swith(e.data.event){
       case 'getData':
       //子頁面初始化獲取數(shù)據(jù)
     } 
      ....//其他事件
   }  
  }
 }
}
//向子頁面發(fā)送數(shù)據(jù)
this.childPage.postMessage({event:'initData',data:this.transforData},location.origin)
//子頁面初始化
mounted(){
 window.onmessage = e => {
  if(typeof e.data === 'string'){
   console.log('傳遞無效信息')
 }else {
  if(e.data.event){
    console.log('正常發(fā)送數(shù)據(jù)')
    swith(e.data.event){
       case 'initData':
        this.initial(e.data.data)
       //子頁面響應(yīng)父頁面數(shù)據(jù)變化
     } 
      ....//其他事件
   }  
  }
 }
 window.opener.postMessage({event:'getData'})//初始化向父頁面索取數(shù)據(jù)
 window.opener.onunload = () => {
    window.close()//監(jiān)聽到父頁面關(guān)閉后,子頁面自動關(guān)閉 
 }
}

下面是每個頁面的iframe交互-兩個頁面間的iframe交互只是需要本頁面監(jiān)聽iframe事件后,向另一個頁面發(fā)送數(shù)據(jù)

<iframe :src='/model/ppt.htm' ref='iframe' id='iframe><iframe>
//向iframe發(fā)送數(shù)據(jù)

this.$refs.iframe.contentWindow.postMessage({event:'onSelectDate',data:this.date},this.$refs.iframe1.src)

//監(jiān)聽iframe的事件也放在mounted的onmessage里

本文正在參加“寫編程博客瓜分千元現(xiàn)金”活動,關(guān)注公眾號“饑人谷”回復(fù)“編程博客”參與活動。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概述 JavaScript出于安全方面的考慮,不允許跨域調(diào)用其他頁面的對象。但在安全限制的同時也給注入iframe...
    npmstart閱讀 2,304評論 0 5
  • 元素會創(chuàng)建包含另外一個文檔的內(nèi)聯(lián)框架(即行內(nèi)框架); 一、align 屬性(不贊成) align屬性規(guī)定ifram...
    puxiaotaoc閱讀 19,966評論 0 14
  • 面試題一:https://github.com/jimuyouyou/node-interview-questio...
    R_X閱讀 1,760評論 0 5
  • 1. 什么是跨域? 跨域一詞從字面意思看,就是跨域名嘛,但實際上跨域的范圍絕對不止那么狹隘。具體概念如下:只要協(xié)議...
    w_zhuan閱讀 622評論 0 0
  • 1. 什么是跨域? 跨域一詞從字面意思看,就是跨域名嘛,但實際上跨域的范圍絕對不止那么狹隘。具體概念如下:只要協(xié)議...
    他在發(fā)呆閱讀 861評論 0 0

友情鏈接更多精彩內(nèi)容