本文详细解析如何利用 window.name 属性实现跨域数据通信。核心思路是通过 iframe 加载外部域页面,利用 window.name 在页面重载时保持不变的特性,将数据从外域传递至本地域代理页面,从而绕过浏览器的同源策略限制,同时确保操作安全。
window.name 跨域传输原理与实现
经过实际测试,该方法效果显著。现将具体实现流程记录如下。
涉及三个页面:
a.com/app.html:主应用页面。 a.com/proxy.html:代理页面,通常为空 HTML 文件,必须与应用页面处于同一域名下。 b.com/data.html:数据源页面,即应用页面需要获取数据的页面。
基本实现步骤如下:
在主应用页面(a.com/app.html)中创建一个 iframe,并将其 src 属性指向数据页面(b.com/data.html)。 数据页面会将所需数据赋值给该 iframe 的 window.name 属性,data.html 的核心代码如下:
<script type="text/javascript">
window.name = 'I was there!'; // 这里是要传输的数据,大小一般为2M,IE和firefox下可以大至32M左右
// 数据格式可以自定义,如json、字符串
</script>
在主应用页面(a.com/app.html)中监听 iframe 的 onload 事件。在事件触发后,立即将 iframe 的 src 指向本地域的代理文件(因代理文件与应用页面同域,故可正常通信)。app.html 的部分核心代码如下:
<script type="text/javascript">
var state = 0,
iframe = document.createElement('iframe'),
loadfn = function() {
if (state === 1) {
var data = iframe.contentWindow.name; // 读取数据
alert(data); //弹出'I was there!'
} else if (state === 0) {
state = 1;
iframe.contentWindow.location = "http://a.com/proxy.html"; // 设置的代理文件
}
};
iframe.src = 'http://b.com/data.html';
if (iframe.attachEvent) {
iframe.attachEvent('onload', loadfn);
} else {
iframe.onload = loadfn;
}
document.body.appendChild(iframe);
</script>
数据获取完成后,销毁该 iframe 以释放内存;此举同时也保障了安全性,防止其他域通过 frame 访问 JS。
<script type="text/javascript">
iframe.contentWindow.document.write('');
iframe.contentWindow.close();
document.body.removeChild(iframe);
</script>
总结而言:iframe 的 src 属性由外域切换至本地域,跨域数据借助 iframe 的 window.name 从外域传递至本地域。这一机制巧妙规避了浏览器的跨域访问限制,且属于安全操作。