js跨域解决方案

一、问题描述

在页面渲染时需要动态获取iframe子页面的高度,然后重新设置iframe高度,达到自适应的目的,但是由于iframe子页面中也涉及到访问其他系统的页面,这就使得页面渲染时无法获取子页面高度,这里涉及到跨域访问子页面问题。

二、什么是跨域

我们经常会在页面上使用ajax请求访问其他服务器的数据,此时,客户端会出现跨域问题.

跨域问题是由于javascript语言安全限制中的同源策略造成的.

简单来说,同源策略是指一段脚本只能读取来自同一来源的窗口和文档的属性,这里的同一来源指的是主机名、协议和端口号的组合.

例如:

URL

说明

是否允许通信

http://www.a.com/a.js http://www.a.com/b.js

同一域名下

允许

http://www.a.com/lab/a.js http://www.a.com/script/b.js

同一域名下不同文件夹

允许

http://www.a.com:8000/a.js http://www.a.com/b.js

同一域名,不同端口

不允许

http://www.a.com/a.js https://www.a.com/b.js

同一域名,不同协议

不允许

http://www.a.com/a.js http://70.32.92.74/b.js

域名和域名对应ip

不允许

http://www.a.com/a.js http://script.a.com/b.js

主域相同,子域不同

不允许

http://www.a.com/a.js http://a.com/b.js

同一域名,不同二级域名(同上)

不允许(cookie这种情况下也不允许访问)

http://www.cnblogs.com/a.js http://www.a.com/b.js

不同域名

不允许

三、解决方案

1、通过修改document.domain来跨子域

基于iframe实现的跨域要求两个域具有aa.xx.com,bb.xx.com这种特点,也就是两个页面必须属于一个基础域(例如都是xxx.com,或是xxx.com.cn),使用同一协议(例如都是 http)和同一端口(例如都是80),这样在两个页面中同时添加document.domain,就可以实现父页面调用子页面的函数。网上有很多例子,很容易找到,不过该解决方案存在一些问题:

a 安全性,当一个站点(b.a.com)被攻击后,另一个站点(c.a.com)会引起安全漏洞

b如果一个页面中引入多个iframe,要想能够操作所有iframe,必须都得设置相同domain。这样会导致很多动态创建iframe的插件无法使用,比如说富文本编辑插件。

2、基于script标签实现跨域

script标签本身就可以访问其它域的资源,不受浏览器同源策略的限制,可以通过在页面动态创建script标签,代码如下:

var script = document.createElement('script'); script.src = "http://aa.xx.com/js/*.js"; document.body.appendChild(script);

这样通过动态创建script标签就可以加载其它域的js文件,然后通过本页面就可以调用加载后js文件的函数,这样做的缺陷就是不能加载其它域的文档,只能是js文件,jsonp便是通过这种方式实现的,jsonp通过向其它域传入一个callback参数,通过其他域的后台将callback参数值和json串包装成javascript函数返回,因为是通过script标签发出的请求,浏览器会将返回来的字符串按照javascript进行解析执行,实现了域与域之间的数据传输。 jquery中对jsonp的支持也是基于此方案。

3、通过iframe嵌套来实现跨域

前提,www.a.com下a.html,a.html内iframe调用了www.b.com下的b.html,b.html下iframe调用了www.a.com下的c.html b.html是不无法直接访问a.html的对象,因为涉及到跨域,但可以访问parent,同样c.html的parent可以访问b.html。c.html和a.html同域,是可以访问a下的对象的。parent.parent.js对象!

<!--[endif]-->

本质上就是利用parent.parent实现对父父页面中js的回调

4、使用apache反向代理实现跨域

由于前端解决跨域问题的局限性比较大,对于 Ajax 跨域或是 iframe 跨域,建议用服务器端解决方案。

此方案的原理是接受客户端发来的请求后,经由本域服务器代理向目标服务器发送请求,并将响应数据返回给客户端。

反向代理(Reverse Proxy),顾名思义,就是代理的反向功能。我们使用代理,可以访问一些我们所不能直接访问到的网络,或者可以隐藏自己的真实身份。而反向代理,可以在不暴露内部服务器的情况下,让外部用户访问我们内部、防火墙后的服务。

使用反向代理主要有以下好处:

u 请求的统一控制,包括设置权限、过滤规则等;

u 隐藏内部服务真实地址,暴露在外的只是反向代理服务器地址;

u 实现负载均衡,内部可以采用多台服务器来组成服务器集群,外部还是可以采用一个地址访问;

u 解决Ajax跨域问题。

u 作为真实服务器的缓冲,解决瞬间负载量大的问题。

总结这里列举的四种方案各有优缺点:

第一种方案:开发比较简单,但是安全性和兼容性比较差。

第二种方案:使用与单向跨域,工作量稍大。

第三种方案:能比较好的解决双向调用,但是工作量稍大。

第四种方案:可以适用用于几乎所有的跨域访问,而且只需要要一个域中进行开发,另一个域可以提供任何类型格式的数据。缺点是这种方案经过了中间代理,所以延迟可能稍微大一点。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券