window.name + iframe跨域实例

window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因新页面的载入而进行重置。

在getDomainData.html页面中,我们怎么把data.html页面载入进来呢?显然我们不能直接在getDomainData.html页面中通过改变window.location来载入data.html页面,因为我们想要即使getDomainData.htmll页面不跳转也能得到data.html里的数据。答案就是在getDomainData.html页面中使用一个隐藏的iframe来充当一个中间人角色,由iframe去获取data.html的数据,然后getDomainData.html再去得到iframe获取到的数据。

充当中间人的iframe想要获取到data.html的通过window.name设置的数据,只需要把这个iframe的src设为http://localhost:8001/data.html就行了。然后getDomainData.html想要得到iframe所获取到的数据,也就是想要得到iframe的window.name的值,还必须把这个iframe的src设成跟getDomainData.html页面同一个域才行,不然根据前面讲的同源策略,getDomainData.html是不能访问到iframe里的window.name属性的。这就是整个跨域过程。

1. 在文件夹test下新建getDomainData.html和null.html文件,null.html为一个空文件,getDomainData.html代码如下

<!DOCTYPE html>
<
html> <head> <title>跨域获取数据</title> <meta charset="utf-8"> <script type="text/javascript"> function domainData(url, fn) { var isFirst = true; var iframe = document.createElement('iframe'); iframe.style.display = 'none'; var loadfn = function(){ if(isFirst){ iframe.contentWindow.location = 'http://localhost:8000/null.html'; isFirst = false; } else { fn(iframe.contentWindow.name); iframe.contentWindow.document.write(''); iframe.contentWindow.close(); document.body.removeChild(iframe); iframe.src = ''; iframe = null; } }; iframe.src = url; if(iframe.attachEvent){//IE 支持 iframe 的 onload 事件,不过是隐形的,需要通过 attachEvent 来注册。 iframe.attachEvent('onload', loadfn); } else { iframe.onload = loadfn; //IE6 IE7 IE8 中无法通过为属性赋值方式为 IFRAME 元素绑定 load 事件处理函数 } document.body.appendChild(iframe); } </script> </head> <body> </body> <script type="text/javascript"> domainData('http://localhost:8001/data.html', function(data){ alert(data); }); </script> </html>

2. 在文件夹test1下新建data.html,代码如下

<script type="text/javascript">
    window.name = "跨域得到的数据";
</script>

3. 通过node static搭建本地服务

 

 

即端口8000上的页面要跨域访问端口8001上的数据

4. 访问http://localhost:8000/getDomaindata.html读取到http://localhost:8001/data.html中window.name的数据

注意:IE6 IE7 IE8 中无法通过为属性赋值方式为 IFRAME 元素绑定 load 事件处理函数

有三种方式可以解决这个兼容性问题

//1.直接为 HTMLIFrameElement.onload 属性为 IFRAME 标记赋值事件处理函数
//<iframe id="ifarmeB" onload="iframeLoadB()"></iframe>
//2.使用 HTMLIFrameElement.setAttribute 方法为 IFRAME 标记赋值事件处理函数
//iframeA.setAttribute("onload","iframeLoadA()");
//3.使用事件监听方式为 IFRAME 的 onload 事件绑定处理函数
//addEvent("load",iframeA,iframeLoadA);
function addEvent(element, eventName, fn){
    if(element.attachEvent) {
        element.attachEvent("on" + eventName, fn);
    }
    else {
        element.addEventListener("on" + eventName, fn, false);
    }
}

 

posted on 2015-08-23 13:44  SherryIsMe  阅读(2270)  评论(0编辑  收藏  举报

导航