window.name 跨域

2019-7-7 14:02| 作者: admin| 查看: 573| 评论: 0|来自: 蚂蚁部落

window.name属性非常的简单,它能够设置或者获取当前窗口对象的名称。

关于它的基本用法可以参阅window.name 用法一章节。

但是此属性的某些特点,又让其有了其他使用价值,那就是跨域操作。

特别说明:如果不考虑浏览器兼容性,更加推荐采用window.postMessage()实现跨域。

一.为什么可以进行跨域操作:

每一个页面都对应一个window窗口,一个窗口可以打开不同的页面。

无论这些页面同域还是不同域,它们都共享一个window.name,这一点是实现跨域的关键。

window.name属性可以容纳的数据大小大致是2M,数据量还是可以的,不同的浏览器可能会有所不同。

关于什么是跨域可以参阅同源策略详解一章节。

下面对window.name属性的特性进行一下验证操作:

(1).首先在一个窗口打开蚂蚁部落(www.softwhy.com)。

(2).然后在谷歌开发者工具控制台设置window.name的值为"蚂蚁部落":

a:3:{s:3:\"pic\";s:43:\"portal/201907/07/142023wn8um7nnofb7s3v8.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

(3).然后在同一个窗口打开百度的首页,很明显这不同域的。

在此窗口下的控制台获取设置的window.name属性值:

a:3:{s:3:\"pic\";s:43:\"portal/201907/07/142039gh1m3mm75osx7xms.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

可以看到无论是否同域,都会共享一个window.name。

二.实现跨域操作:

通过下面的代码实例简单演示一下利用window.name实现跨域操作。

假设有如下三个页面:

(1).x.com/getDate.html:获取数据的页面

(2).x.com/proxy.html:代理页面,与获取数据页面同域

(3).y.com/date.html:数据页面,getDate.html将从其获取数据

我们的需求是getDate.html利用window.name从date.html页面获取相关数据。

date.html页面中的数据如下:

[JavaScript] 纯文本查看 复制代码
let date = {
    webName:"蚂蚁部落",
    address:"青岛市南区"
}
window.name = date;

window.name数据可以共享,当前窗口加载date.html页面后,再加载getDate.html页面。

getDate.html页面可以获取date.html中设置的数据,但是总不能采取如下两种措施:

(1).date.html有代码可以在同一窗口跳转到getDate.html页面。

(2).打开date.html页面,然后再手动在同一窗口打开getDate.html页面。

上述两种方式过于死板,在实际项目中使用不太现实,不过可以利用<iframe>另辟蹊径。

实现跨域操作步骤如下:

(1).在getDate.html页面创建一个隐藏的<iframe>:

动态创建一个<iframe>,并将其设置为隐藏状态,不影响页面的正常布局。

并将此<iframe>的src属性值设置为y.com/date.html,那么框架的window.name会获取到对应的数据。

(2).监听<iframe>的load事件,进行相应操作:

由于是跨域getDate.html页面无法获取在<iframe>加载的y.com/date.html中的数据。

但是可以当y.com/date.html页面在框架中加载完成之后,再在框架加载proxy.html页面。

由于proxy.html和getDate.html共享window.name,并且proxy.html与getDate.html是同域的。

(3).核心代码展示:

下面给出操作的核心代码部分,比较简单:

[JavaScript] 纯文本查看 复制代码
let state = 0, 
    iframe = document.createElement('iframe'),
    loadfn = ()=> {
        if (state === 1) {
            // 读取数据
            let data = iframe.contentWindow.name;    
            // 其他代码
        } else if (state === 0) {
            state = 1;
            // 加载同域代理文件
            iframe.contentWindow.location = "http://x.com/proxy.html"; 
        }  
    };

iframe.src = 'http://y.com/date.html';
if (iframe.attachEvent) {
  iframe.attachEvent('onload', loadfn);
} else {
  iframe.onload  = loadfn;
}
document.body.appendChild(iframe);

上述代码比较简单,下面做简略说明:

(1).动态创建一个iframe,并初始化一个状态标记state。

(2).初始设置iframe加载跨域date.html页面。

(3).通过load事件监听iframe加载的页面是否已经加载完成,如果完成则执行loadfn函数。

(4).首先加载的是跨域数据文件,加载完成后执行loadfn函数,如果state等于0,那说明没有加载同域代理文件,于是通过iframe.contentWindow.location = "http://x.com/proxy.html"在iframe窗口加载同域代理文件,并将 state值设置为1。

(5).如果同域代理文件在iframe中加载完成,再次出发load时间,再执行loadfn函数,此时state变为1,表示同域代理文件加载完成,你可以顺畅的获取数据了。

删除iframe:

当我们获取数据并进行相关操作完毕后,那么动态创建的iframe也就无用了。

可以通过如下JavaScript将其删除:

[JavaScript] 纯文本查看 复制代码
iframe.contentWindow.document.write('');
iframe.contentWindow.close();
document.body.removeChild(iframe);

上面的代码都是一些核心演示,需要根据自己的需要进行改造。


鲜花

握手

雷人

路过

鸡蛋

最新评论

返回顶部