JS跨域之window.name实现的跨域数据传输

作者:工具松鼠

时间:2026-10-24

浏览:519

本文介绍利用window.name属性在页面跳转后仍保留值的特性,结合iframe加载跨域页面并跳转至本地代理页,实现安全的数据跨域传输。通过设置window.name并在iframe onload事件中切换src,可绕过浏览器同源策略限制,获取其他域数据。

文章目录

一、 window.name的性质

window.name具备一个独特特性, 当页面设定了window.name后, 即便执行页面跳转location.href=...,该window.name依然保持不变。

我们可以在控制台进行验证:

// 打开浏览器输入URL:www.jb51.net
//F12打开控制台
//在控制台中依次输入下面内容

//输入
window.name;
//返回
''

//输入
window.name='test';
//返回
'test'

//输入
location.href='http://www.baidu.com';
//返回
http://www.baidu.com

//输入
window.name;
//返回
'test'

借助此特性,即可获取其他域的数据。

二、 跨域请求

已知使用iframe的src属性,能够加载不同域的网页, 也可通过$('iframe').contentWindow获取iframe内页面的window对象, 但该window对象中可访问的属性极为有限。

//控制台输入
Object.keys($('iframe').contentWindow);

//返回
["postMessage", "blur", "focus", "close", "parent", "opener", "top", "length", "frames", "closed", "location", "self", "window"]

尝试访问其他属性将引发错误:

Uncaught DOMException: Blocked a frame with origin "..." from accessing a cross-origin frame.

若使用iframe加载同域页面,访问$('iframe').contentWindow属性则不会报错,它代表iframe内页面的完整window对象。

三、整合

基于window.name的特性,可在iframe中加载跨域页面。

页面加载完成后,令其设置自身的window.name, 随后执行当前页面的跳转,目标为与iframe外部页面同域的页面, 此时window.name保持不变。

至此,iframe内外处于同一域,且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从外域传递到本地域。此方法巧妙规避了浏览器跨域访问限制,同时保持安全操作。

参考文章:window.name Transport、Session variables without cookies

另一篇 JS跨域(Access-Control-Allow-Origin)前后端解决方案详解 提供更详细的浏览器跨域问题介绍

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章