原理
window.name有以下特点
- 每个窗口都有独立的window.name与之对应;
- 在一个窗口的生命周期中(被关闭前),窗口载入的所有页面同时共享一个window.name,每个页面对window.name都有读写的权限;
- window.name一直存在与当前窗口,即使是有新的页面载入也不会改变window.name的值;
- window.name可以存储不超过2M的数据,数据格式按需自定义。
实操
例如 我在a.html页面中想拿b.html页面中的数据,由于同源策略限制,我们不能通过window.location.href
更新页面来获得数据,我们可以用一个隐藏的iframe
作为中间的代理(因为iframe不受同源限制),iframe
的src
为"b.html"
,在iframe
页面加载完毕的时候,我们再让iframe
与当前页面属于同一个域下,我们就可以拿到window.name
了。
//a.html
var iframe = document.createElement('iframe');//工具人
iframe.style.display = "none";//工具人隐藏在背后默默付出
var flag = false;
iframe.onload = function () {
if ( flag ) {
var data = iframe.contentWindow.name;//contentWindow.name可以拿到iframe的窗口name值
console.log(data);
iframe.contentWindow.close();//关闭隐藏的页面
document.body.removeChild(iframe);//删除隐藏的页面
} else {
flag = true;
iframe.contentWindow.location = 'http://localhost/demo2.html';//这里因为浏览器同源策略,需要将链接改成与页面一同源的页面(也就是页面二),这里会再次触发load事件,同时这一步也说明了为什么img标签也可以跨域却不用img标签,因为iframe有window对象
}
}
iframe.src = 'http://data/data.html';//跨域,这里窗口已经拿到name,所以上面更换地址后name的值依旧存在
document.body.appendChild(iframe);
总结
给iframe赋值跨域的链接,加载完后触发load事件,此时iframe已经拿到数据放在window.name里,因为浏览器同源策略没法直接拿iframe的name值,所以将iframe的地址改成同域名下的一个网页,在用contentWindow方法获取iframe的name值拿数据