iframe 父子頁(yè)面之間的通信

作為一個(gè)沒(méi)有什么情懷和追求的前端工程師, 是么有怎么考慮過(guò) iframe 用法的, (畢竟從學(xué)習(xí)到工作自己扮演的一直是"前端小妹妹"的角色, 這種臟活累活一般是交給后端臭屌絲的,直到公司的全棧妹子來(lái)找我探討這個(gè)跨域通信的問(wèn)題);

真是不看不知道, 一看嚇一跳. 原來(lái) iframe 也存在跨域的問(wèn)題. 跨域和不跨域情況下和父級(jí)頁(yè)面的通信方式也是略有不同.

文中示例代碼均在github

同域情況下的父子頁(yè)面通信方式

show you the demo

父級(jí)頁(yè)面:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>   
  <script>
    function say() {
      console.log("i am father page");
    }

    function callChild() {
      mySon.window.say();
      mySon.window.document.getElementById('button').innerHTML = '調(diào)用結(jié)束';
    }
  </script>
  <button id="button" onclick="callChild()"> 調(diào)用兒子的方法 </button>
  <iframe name="mySon" src="http://localhost:3000/demo.html?aim=xiaopang" frameborder="0"></iframe>
</body>
</html>

兒子頁(yè)面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>

  <script>
    function say() {
      console.log('i am child page');
    }
    function callFather() {
      parent.say();
      parent.window.document.getElementById('button').innerHTML = '調(diào)用結(jié)束'
    }
  </script>

  <button id="button" onclick="callFather()"> 調(diào)用爸爸的方法 </button>
</body>
</html>

以上示例功能

  • 調(diào)用函數(shù):

    1. 父級(jí)頁(yè)面調(diào)用子頁(yè)面的函數(shù) name.window.func();
    2. 子頁(yè)面調(diào)用父級(jí)頁(yè)面的函數(shù) parent.window.func();
  • 訪問(wèn)頁(yè)面元素
    window都拿到了,元素不會(huì)拿骆姐。請(qǐng)自行百度争占。

ps: 注意事項(xiàng):

兒子頁(yè)面加載完成后再進(jìn)行訪問(wèn), 判斷方法:

  1. iframe 上添加 onload 事件;
  2. document.readyState == 'complete';

跨域情況下父子頁(yè)面通信的方法

如果 iframe 所鏈接的是外部的頁(yè)面, 尼瑪, 居然有跨域限制, 有跨域限制, 有跨域限制......

父頁(yè)面向子頁(yè)面?zhèn)鬟f數(shù)據(jù)

跨域情況下的父子頁(yè)面通信的原理大概就是使用 hash / 直接傳參數(shù)搞定;傾向于hash;

  1. 在子頁(yè)面中通過(guò)定時(shí)器監(jiān)聽(tīng) location.hash 的變化就能夠拿到父級(jí)頁(yè)面?zhèn)鱽?lái)的數(shù)據(jù)啦;
  2. 一次性的從父頁(yè)面 get 過(guò)來(lái)的參數(shù)中提取有用的部分,就 OK 啦;

子頁(yè)面向父頁(yè)面?zhèn)鬟f數(shù)據(jù)

跨域情況下,子頁(yè)面向父頁(yè)面?zhèn)鬟f數(shù)據(jù)的實(shí)現(xiàn)原理是使用一個(gè)代理的 iframe (就像是跨域請(qǐng)求中的代理服務(wù)器一樣), 并且保持代理的子頁(yè)面和父級(jí)頁(yè)面是同域的此時(shí)就可以通過(guò), window.top 或者 window.parent.parent 就可以獲取父級(jí)頁(yè)面的引用啦. 嗶哩嗶哩...

不 bb 上 demo

父級(jí)頁(yè)面:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
   我是彩筆圈圈

   <script>
     var i = 1;
     function say(data) {
       console.log('我是爸爸' + data);
     }

     function add() {
       document.getElementById('quanquan').setAttribute('src', 'http://localhost:3000/demo2.html?aim=quanquan#'+ ++i)
     }

   </script>
   <button onclick="add()">+1</button>
   <iframe id='quanquan' src="http://localhost:3000/demo2.html?aim=quanquan#1" frameborder="0"></iframe>
</body>
</html>

子級(jí)頁(yè)面:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script>
    var hash = location.hash, i = 1;
    function checkData() {
      if(hash !== location.hash) {
        hash = location.hash
        console.log('我是兒子' + hash);
      } 
    }
    function say() {
      console.log('i am child page');
    }
    function callFather() {
      document.getElementById('quanquan').setAttribute('src', 'http://localhost:4000/proxy.html#'+ ++i)
    }
    setInterval(checkData, 1e3);
  </script>
  <button id="button" onclick="callFather()"> 調(diào)用爸爸的方法 </button>
  <iframe id="quanquan" style="display: none" src="http://localhost:4000/proxy.html#1" frameborder="0"></iframe>
</body>
</html>

proxy 中轉(zhuǎn)頁(yè)面:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>proxy</title>
</head>
<body>
  <script>
    var hash = location.hash;
    function callGrandFather(data) {
      window.top.say(data);
    };
    function checkData() {
      if ( hash !== location.hash ) {
        callGrandFather(location.hash);
        hash = location.hash;
      }
    }
    setInterval(checkData, 1e3);
  </script>
</body>
</html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市领舰,隨后出現(xiàn)的幾起案子湖饱,更是在濱河造成了極大的恐慌脓鹃,老刑警劉巖傻昙,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異梳猪,居然都是意外死亡麻削,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門春弥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)呛哟,“玉大人,你說(shuō)我怎么就攤上這事匿沛∩ㄔ穑” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵逃呼,是天一觀的道長(zhǎng)鳖孤。 經(jīng)常有香客問(wèn)我,道長(zhǎng)蜘渣,這世上最難降的妖魔是什么淌铐? 我笑而不...
    開(kāi)封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任肺然,我火速辦了婚禮蔫缸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘际起。我一直安慰自己拾碌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布街望。 她就那樣靜靜地躺著校翔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪灾前。 梳的紋絲不亂的頭發(fā)上防症,一...
    開(kāi)封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音哎甲,去河邊找鬼蔫敲。 笑死,一個(gè)胖子當(dāng)著我的面吹牛炭玫,可吹牛的內(nèi)容都是我干的奈嘿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼吞加,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼裙犹!你這毒婦竟也來(lái)了尽狠?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤叶圃,失蹤者是張志新(化名)和其女友劉穎袄膏,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體掺冠,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哩陕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赫舒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悍及。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖接癌,靈堂內(nèi)的尸體忽然破棺而出心赶,到底是詐尸還是另有隱情,我是刑警寧澤缺猛,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布缨叫,位于F島的核電站,受9級(jí)特大地震影響荔燎,放射性物質(zhì)發(fā)生泄漏耻姥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一有咨、第九天 我趴在偏房一處隱蔽的房頂上張望琐簇。 院中可真熱鬧,春花似錦座享、人聲如沸婉商。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)丈秩。三九已至,卻和暖如春淳衙,著一層夾襖步出監(jiān)牢的瞬間蘑秽,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工箫攀, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留肠牲,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓匠童,卻偏偏與公主長(zhǎng)得像埂材,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子汤求,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

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

  • 1. 什么是跨域俏险? 跨域一詞從字面意思看严拒,就是跨域名嘛,但實(shí)際上跨域的范圍絕對(duì)不止那么狹隘竖独。具體概念如下:只要協(xié)議...
    w_zhuan閱讀 515評(píng)論 0 0
  • 1. 什么是跨域裤唠? 跨域一詞從字面意思看,就是跨域名嘛莹痢,但實(shí)際上跨域的范圍絕對(duì)不止那么狹隘种蘸。具體概念如下:只要協(xié)議...
    他在發(fā)呆閱讀 822評(píng)論 0 0
  • 前言 原文地址:前端跨域總結(jié) 博主博客地址:Damonare的個(gè)人博客 相信每一個(gè)前端er對(duì)于跨域這兩個(gè)字都不會(huì)陌...
    秦至閱讀 1,398評(píng)論 4 51
  • 轉(zhuǎn)載:http://damonare.github.io/2016/10/30/%E5%89%8D%E7%AB%A...
    壯哉我大前端閱讀 539評(píng)論 2 9
  • 你說(shuō)鳶尾寄寂航瞭,與子相惜;后來(lái)花開(kāi)如海坦辟,兩生相憶刊侯。 你說(shuō)引弓落月,子規(guī)哀啼锉走;后來(lái)天地玄黃滨彻,瀟瀟暮雨。 你說(shuō)煙雨畫堂挪蹭,...
    木筆喬喬閱讀 444評(píng)論 0 1