js 跨域

 在使用iframe来开发嵌套网页的web站点时,js跨域调用是个头疼的问题。一方面,浏览器说这不安全,不让你调用;另一方面,开发者说我们要交互,必须要调用。作者是个开发者,必须从开发者的需求出发,解决js跨域调用问题。在这里总结下js跨域调用的各种方法,并将目前项目所使用的方案分享给大家。

1.降低浏览器安全级别。。。。。。。。。。。。。。。是的,非常不实际。

2.设置域名。适用于子域名相同的页面。例如父页面域名为xxx.a.com,子页面域名为yyy.a.com,二级域名是相同的,可以通过脚本设置两个页面的域名都为a.com来进行互相调用,该方法非常简单,js代码如下:
  1. document.domain='a.com';  
document.domain='a.com';
该方法的缺陷是明显的,首先两个域名必须有子域名相同,其次如果使用ajax,当在yyy.a.com更改域名为a.com后,ajax请求返回的数据域名也变回了yyy.a.com,某些浏览器也会因安全问题阻止ajax解析。

3.设置hash值。例如url为"xxx.a.com#test",hash值为test。更改hash值不会导致页面刷新,所以js可以通过设置和监听hash来进行通信调用。
    这方法缺点也是很明显的,首先hash在网页设计中常用作为锚点,如果页面本身需要锚点,那么使用hash传递消息会很混乱;其次hash的改变没有相应的事件,所以监听hash需要使用定时器来定时检测;还有hash值是直接暴露在浏览器地址栏中的,也就是顶级窗口的hash消息将是暴露的,不安全。

4.网站代理。所有iframe页面(包括顶级页面)都通过同一个网站来代理请求,可以直接使用顶级窗口来当代理。例如顶级窗口xxx.a.com中嵌套页面yyy.b.com,原先的iframe标签是这样写的
  1. <iframe src='http://yyy.b.com'></iframe>  
<iframe src='http://yyy.b.com'></iframe>
使用顶级窗口的站点xxx.a.com作为代理时,需要这样写
  1. <iframe src='http://xxx.a.com/proxy?url=yyy.b.com'></iframe>  
<iframe src='http://xxx.a.com/proxy?url=yyy.b.com'></iframe>
这样一下就没有跨域问题了,全都是同一个域名!
    嗯,缺点还是要说的,如果yyy.b.com需要请求其他资源,例如js、图片、表单提交等,如果请求的链接写的是相对路径,请求将发给xxx.a.com,而不是yyy.b.com。

5.动态脚本。例如顶级页面xxx.a.com中定义了一个函数haha(),yyy.b.com需要调用该函数,那么yyy.b.com这个页面可以通过创建域名为xxx.a.com的iframe,通过新建的iframe来请求调用haha(),如下代码
  1. <iframe src='http://xxx.a.com/dynamicJs/a'></iframe>  
<iframe src='http://xxx.a.com/dynamicJs/a'></iframe>
该iframe的内容如下
  1. <script type='text/javascript'>   
  2. top.haha();   
  3. </script>  
<script type='text/javascript'>
top.haha();
</script>
其中的top变量直接指向了顶级页面,也就是xxx.a.com,由于新建的iframe的域名与顶级域名一致,所以是可以直接调用haha函数滴!
    缺点。因为要通过http请求来调用脚本,网络较差时,实时性很差!

6.postMessage。消息传递机制,这是HTML5的内容(不要以为HTML5离咱们多远。IE8以上、chrome3以上、firefox3以上都是支持该机制滴)。先说明下该函数,函数用于页面间传递消息,原型为
  1. otherWindow.postMessage(message, targetOrigin);  
otherWindow.postMessage(message, targetOrigin);
otherWindow是接收信息的window对象,可以是iframe的contentWindow,top变量、parent变量、frames['frameId']变量等;message是要传递的消息;targetOrigin是对otherWindow变量的限制条件,例如,'*'表示不作限制,'http://xxx.a.com'表示otherWindow必须是xxx.a.com域名下。
    发送信息的窗口使用postMessage来发送信息。对于接收信息的窗口,分浏览器不同监听的事件也不同,接受信息的代码如下例子
  1. if(window.attachEvent){ //IE浏览器   
  2.     window.attachEvent('onmessage'function(event) {   
  3.         alert(event.data);   
  4.     });   
  5. else { //firefox和chrome   
  6.     window.addEventListener('message'function(event){   
  7.         alert(event.data);   
  8.     }, false)   
  9. }  
if(window.attachEvent){ //IE浏览器
    window.attachEvent('onmessage', function(event) {
        alert(event.data);
    });
} else { //firefox和chrome
    window.addEventListener('message', function(event){
        alert(event.data);
    }, false)
}
呃。。。缺点还是得说的,由于存在庞大的IE6与IE7用户,该方法的浏览器兼容很糟糕。

7.这是5与6的结合,也是目前作者所参与项目所使用的方案。判断浏览器是否支持消息传递机制,支持的话使用消息传递,否则使用动态脚本。附件为该方法的一个demo,outer.html为顶级页面,inner.html为子页面,proxy.php为动态脚本(在使用消息传递时不会使用到),该demo演示了通过点击顶级页面outer.html的按钮后,调用inner.html中的函数。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值