iframe 之间传值 、iframe与外部之间传值及iframe跨域的问题解决思路(提供完整例子)

您所在的位置:网站首页 iframe跨域通信有可能会出错误吗 iframe 之间传值 、iframe与外部之间传值及iframe跨域的问题解决思路(提供完整例子)

iframe 之间传值 、iframe与外部之间传值及iframe跨域的问题解决思路(提供完整例子)

2024-06-10 01:28| 来源: 网络整理| 查看: 265

需要、假设

假设 父组件下有两个同级的iframe1子组件与iframe2子组件; 需求是 父组件可以与iframe之间传值,iframe1与iframe2之间也可以相互传值;

不跨域 思路:

1、不跨域情况下,父组件向iframe子组件传值; 方法一、子组件定义函数fn, 父组件 通过iframe的contentWindow获取到子组件fn,并通过fn传值到iframe子组件; 方法二、父组件 通过向iframe的contentWindow添加属性,子组件需要时通过Window[属性名]获取父元素传递的数据; 方法三、子组件使用parent可以获取到父组件的window; 2、不跨域情况下,iframe子组件向父组件传值; 方法一、父元素定义函数getChild并通过向iframe的contentWindow添加getChild方法,子组件通过Window.getChild();传值给父组件; 3、iframe1与iframe2之间也可以相互传值; 方法一、通过子组件iframe1向父组件传值,再通过父组件向子组件iframe2传值可达到目的; 注意:模拟时 需要开启服务器,否则会出现跨域问题! 在这里插入图片描述 不跨域例子 在这里插入图片描述

父组件 index.html

let iframe1 = document.getElementById('iframe1'); let iframe2 = document.getElementById('iframe2'); let fatherData = '父元素数据'; window.fatherData = fatherData; window.onload = () => { iframe1.contentWindow.getData('父元素window.onload后传入到iframe1 的数据'); iframe1.contentWindow.fatherData = fatherData; iframe1.contentWindow.getChild = getChild; iframe1.contentWindow.getIframe2 = getIframe2; } function getChild(data) { console.log('获取到子组件数据', data); } function getIframe2(data) { iframe2.contentWindow.setIframe2(data); }

子组件 iframe1.html

iframe1 iframe1 获取父组件数据 传值给父组件 传值给ifrme2 let demo1Data = ''; function getData(data) { demo1Data = data; console.log('demo1Data', demo1Data); console.log(parent.fatherData); } let btn = document.getElementById('btn'); btn.onclick = () => { console.log(window.fatherData); } let btn1 = document.getElementById('btn1'); btn1.onclick = () => { window.getChild('hhh'); } let btn2 = document.getElementById('btn2'); btn2.onclick = () => { window.getIframe2('ifrme1的数据'); } // // 这里设置定时获取 是因为 子元素先加载完成 父元素才赋值getFatherData方法; // let timer = setInterval(() => { // if (window.getFatherData) { // console.log(window.getFatherData()); // clearInterval(timer); // } // }, 100)

子组件 iframe2.html

iframe2 iframe2 function setIframe2(data) { console.log(data); }

启动服务器 serve.js

var express =require('express'); var app = require('express')(),server =require('http').createServer(app); server.listen(8888); app.use(express.static("./")); app.get('/',function(req,res){ res.sendFile(__dirname + '/index.html'); }); // 终端打印如下信息 console.log('Server running at http://127.0.0.1:8888/');

启动服务器前 先用node 安装 express插件; 启动服务器

node serve.js

结果如图 在这里插入图片描述

跨域 思路:

1、跨域时通过创建代理页面的方式,子组件可以操作父组件方法,但使用范围有限; 2、利用location.hash,父组件给子组件iframe标签的src属性链接后面添加#,子组件通过location.hash获取父组件数据,从而达到父组件操作子组件,如 3、使用postMessage实现跨域通信  postMessage方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。

语法:

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

otherWindow:其他窗口的引用,如 iframe的contentWindow、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。 message:将要发送到其他window的数据。 targetOrigin:指定那些窗口能接收到消息事件,其值可以是字符串 “*” 表示无限制,或者是一个URI。 transfer:是一串和message同时传递的Transferable对象,这些对象的所有权将被转移给消息的接收方,而发送方将不再保留所有权。 postMessage方法被调用时,会在所有页面脚本执行完毕之后像目标窗口派发一个 MessageEvent 消息,该MessageEvent消息有四个属性需要注意:

type:表示该message的类型 data:为 postMessage 的第一个参数 origin:表示调用postMessage方法窗口的源 source:记录调用postMessage方法的窗口对象 在这里插入图片描述 1,2 例子 在这里插入图片描述 父组件father下的index.html,serve.js

index.html

let iframe1 = document.getElementById('iframe1'); let fatherData = '父元素数据'; function getFatherData() { console.log('跨域子组件操作父组件', fatherData); }

serve.js

var express =require('express'); var app = require('express')(),server =require('http').createServer(app); server.listen(7777); app.use(express.static("./")); app.get('/',function(req,res){ res.sendFile(__dirname + '/iframe1.html'); }); // 终端打印如下信息 console.log('Server running at http://127.0.0.1:7777/');

子组件child下的iframe1.html,serve.js iframe1.html

iframe1 iframe1 操作父元素方法 跨域 console.log('location.hash', location.hash); let btn = document.getElementById('btn'); btn.onclick = () => { if (!document.getElementById('proxy')) { let iframe = document.createElement('iframe'); iframe.setAttribute('style', 'display: none;') iframe.setAttribute('JSON', '跨域数据'); iframe.setAttribute('src', 'http://127.0.0.1:7777/proxy.html') document.body.appendChild(iframe); } else { document.getElementById('proxy').src = 'http://127.0.0.1:7777/proxy.html'; } // console.log(parent); // console.log('window.name', window.name); }

serve.js

var express =require('express'); var app = require('express')(),server =require('http').createServer(app); server.listen(5555); app.use(express.static("./")); app.get('/',function(req,res){ res.sendFile(__dirname + '/index.html'); }); // 终端打印如下信息 console.log('Server running at http://127.0.0.1:5555/');

效果 在这里插入图片描述

3.使用postMessage实现跨域通信 例子 模拟跨域的serve.js与1、2一样; 父组件father下的index.html

给子组件传值 let iframe1 = document.getElementById('iframe1'); let btn = document.getElementById('btn'); btn.onclick = () => { iframe1.contentWindow.postMessage("父组件给子组件的数据", "http://127.0.0.1:5555/iframe1.html") } window.addEventListener('message', function(event) { console.log('event', event); }, false);

子组件child下的iframe1.html

iframe1 iframe1 给父组件传值 let btn = document.getElementById('btn'); btn.onclick = () => { top.postMessage("子组件给父组件的数据", 'http://127.0.0.1:7777/index.html') } window.addEventListener('message', function(event) { console.log('event', event); }, false);

效果

在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3