一、同源策略
同源策略是浏览器的一种安全策略,它可以防止一个源加载的文档或脚本与来自另一个源的资源进行交互。同源是指协议、主机、端口号均相同。
因此,同源限制会导致iframe无法通过JavaScript来访问其父页面,除非两者处于同一个源。
二、跨域问题
跨域是指在同一页面下,一个域名的内容访问了另一个域名的资源,这时浏览器会阻止这种行为。
解决跨域的方法有多种,其中iframe跨域通信就是一种。
三、iframe实现跨域通信
1、使用postMessage
postMessage是HTML5引入的一种新特性,用于在跨域的两个窗口之间传递数据。
该方法基于事件模型,传递的消息只有在对方窗口正确响应的情况下,才能接收到。
// 父页面代码 var ifr = document.getElementById('childFrame'); ifr.contentWindow.postMessage('你好子窗口', 'http://www.child.com'); window.addEventListener('message', function(e) { if (e.origin === 'http://www.child.com') { console.log(e.data); } }, false);
// 子页面代码 window.addEventListener('message', function(e) { if (e.origin === 'http://www.parent.com') { console.log(e.data); e.source.postMessage('你好父窗口', 'http://www.parent.com'); } }, false);
2、使用location.hash
在同一个域名下,当改变浏览器的地址栏时,会触发hashchange事件。因此,可以通过修改iframe的location.hash值,来实现同源下的跨窗口通信。
// 父页面代码 var ifr = document.getElementById('childFrame'); txt.onkeyup = function() { ifr.src = ifr.src.split('#')[0] + '#' + txt.value; }; window.addEventListener('hashchange', function() { console.log(ifr.contentWindow.location.hash); }, false);
// 子页面代码 window.onhashchange = function() { console.log(location.hash); parent.window.location.hash = location.hash; };
3、使用window.name
window.name属性在同一窗口下,即使页面跳转,值也不会发生变化。因此,可以通过给iframe的window.name属性赋值,来实现同源下的跨窗口通信。
// 父页面代码 var ifr = document.getElementById('childFrame'); ifr.onload = function() { ifr.contentWindow.name = '你好子窗口'; }; window.onmessage = function(e) { console.log(e.data); };
// 子页面代码 window.name = '你好父窗口'; window.onload = function() { window.parent.postMessage(window.name, '*'); };
四、总结
通过上述三种方法,我们可以在同一个页面的iframe之间实现跨域通信。postMessage是HTML5的推荐方法,具有较高的可靠性和安全性。而location.hash和window.name则适用于同一源的情况,但其实现起来相对较为简单。