需求描述

在工作中,我们会遇到一些需求,使用iframe嵌套另一个页面,这个页面大部分情况下不会部署在父页面相同的域名下,但是又需要父子页面进行数据交互,那么我们该怎么处理呢?

开始上手

上代码

父页面

 1<!DOCTYPE html>
 2<html lang="en">
 3  <head>
 4    <meta charset="UTF-8" />
 5    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
 6    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 7    <link rel="stylesheet" type="text/css" href="./common.css" />
 8    <title>Document</title>
 9  </head>
10  <body>
11    <h2>父页面</h2>
12    <button onclick="doAction()">❤ 点击触发父页面的事件 ❤</button>
13    <br />
14    <iframe
15      id="iframeContainer"
16      name="iframePage"
17      src="./iframe-page.html"
18      frameborder="0"
19      scrolling="no"
20    >
21    </iframe>
22    <script>
23   
24      const doAction = () => {
25        console.log("父页面的事件");
26      };
27    </script>
28  </body>
29</html>
30
31

iframe页面

 1<!DOCTYPE html>
 2<html lang="en">
 3  <head>
 4    <meta charset="UTF-8" />
 5    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
 6    <meta
 7      queryName="viewport"
 8      content="width=device-width, initial-scale=1.0"
 9    />
10    <link rel="stylesheet" type="text/css" href="./common.css" />
11    <title>Document</title>
12  </head>
13  <body style="background-color: black">
14    <h2>iframe页面</h2>
15    <button onclick="iframeDoAction()">❤ 点击触发iframe页面的事件 ❤</button>
16    <script>
17      const iframeDoAction = () => {
18        console.log("iframe页面的事件:iframeDoAction");
19      };
20      
21    </script>
22  </body>
23</html>
24

父向子传值

方法一:通过URL传参

父页面添加代码

 1 
 2      const iframeDom = document.getElementById("iframeContainer");
 3      let url = iframeDom.src + "?id=1&name=糖豆豆"; 
 4      document.getElementById("iframeContainer").src = url;
 5      

iframe页面添加代码

 1      function getUrlQuery(queryName) {
 2        var reg = new RegExp("(^|&)" + queryName + "=([^&]*)(&|$)");
 3        var r = window.location.search.substr(1).match(reg);
 4        if (r != null) return r[2];
 5        return null;
 6      }
 7      window.onload = function () {
 8        console.log("iframe页面的事件:window.onload");
 9        console.log(getUrlQuery("id"), decodeURIComponent(getUrlQuery("name")));
10      };
11      

方法二:通过window.postMessage()方法

父页面添加代码

 1      const doAction = () => {
 2        console.log("父页面的事件");
 3        let send = document.getElementById("iframeContainer").contentWindow;
 4        send.postMessage("我是父页面发的数据", "*");
 5      };
 6      

iframe页面添加代码

 1 
 2      const iframeReceiveData = (data) => {
 3        console.log("iframe页面的事件:iframeReceiveData");
 4                console.log(data)
 5      };
 6      window.onload = function(){
 7            window.addEventListener('message',function(e){
 8                iframeReceiveData(e.data)
 9            })
10       }
11      

注意事项

postMessage方法有三个参数

  • 参数1 :发送的数据;
  • 参数2 :哪些窗口能收到消息事件,用来指定接收消息事件的窗口,其值可以是一个URI或者字符串”*“(表示无限制)举个栗子:window.postMessage(‘hello!’, ‘http://127.0.0.1:5005’);
  • 参数3:是一串和 message 同时传递的 Transferable 对象。这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。

接收postMessage方的怎么用呢?

  • e.source —消息源,消息发送的窗口/iframe
  • e.origin — 消息源的URI,用来验证数据源
  • e.data — 数据

子向父传值

方法一:通过通过全局变量方式处理

父页面添加代码

 1  window.onload = function(){
 2            console.log(document.getElementById('iframeContainer').contentWindow.commonData4)
 3            console.log(document.getElementById('iframeContainer').contentWindow.commonData5)
 4            console.log(document.getElementById('iframeContainer').contentWindow.commonData6)
 5            
 6            document.getElementById('iframeContainer').contentWindow.commonData6()
 7         }

iframe页面添加代码

 1 var commonData4 = { name: "xiaojin", id: 1 };
 2      var commonData5 = 'xiaojin'
 3      var commonData6 = ()=>{console.log(123)}

一起来看一下效果吧

方法二:通过通过window.parent.postMessage()方法

父页面添加代码

 1      
 2        window.onload = function(){
 3            window.addEventListener('message',function(e){
 4                console.log(e.data)
 5            })
 6      
 7

iframe页面添加代码

 1 
 2      const iframeDoAction = () => {
 3        console.log("点击触发iframe页面的事件:iframeDoAction");
 4        window.parent.postMessage("I am xiaojin", "*");
 5      };
 6      

一起来看一下效果吧~

个人笔记记录 2021 ~ 2025