javascript跨域有两种状况:
1、基于同一父域的子域之间,如:a.c.com和b.c.com
2、基于不一样的父域之间,如:www.a.com和www.b.com
3、端口的不一样,如:www.a.com:8080和www.a.com:8088
4、协议不一样,如:http://www.a.com和https://www.a.com javascript
对于状况3和4,须要经过后台proxy来解决,具体方式以下:
a、在发起方的域下建立proxy程序
b、发起方的js调用本域下的proxy程序
c、proxy将请求发送给接收方并获取相应数据
d、proxy将得到的数据返回给发起方的js html
代码和ajax调用一致,其实这种方式就是经过ajax进行调用的java
而状况1和2除了经过后台proxy这种方式外,还能够有多种办法来解决: ajax
1、document.domain+iframe(只能解决状况1):
a、在发起方页面和接收方页面设置document.domain,并将值设为父域的主域名(window.location.hostname)
b、在发起方页面建立一个隐藏的iframe,iframe的源是接收方页面
c、根据浏览器的不一样,经过iframe.contentDocument || iframe.contentWindow.document来得到接收方页面的内容
d、经过得到的接收方页面的内容来与接收方进行交互
这种方法有个缺点,就是当一个域被攻击时,另外一个域会有安全漏洞出现。 json
2、 动态建立script(也就是jsonp)跨域
a、在发起方页面动态加载一个script,script的URL指向接收方的一个处理地址(后台),该地址返回的javascript方法会被执行,另外URL中能够传入一 些参数,该方法只支持GET方式提交参数。 浏览器
b、加载的script能够在调用跨域js方法后再作一些本身的处理安全
3、location.hash+iframe: dom
a、发起方建立一个隐藏的iframe,iframe的源指向接收方的页面,并经过接收方页面的hash值来传送数据
b、发起方建立一个定时器,定时检查本身的location.hash并做相应的处理
c、接收方建立一个隐藏的iframe,iframe的源指向发起方所在域的一个代理页面,并将接收方根据发起方传入的数据而处理后的数据经过代理页面的hash值来传送
d、接收方建立一个定时器,定时检查本身的location.hash并做相应的处理
e、代理页面建立一个定时器,定时检查本身的location.hash并同步更新发起方页面的hash值 www.a.com/a.html#aaa,其中#aaa就是location.hash值 post
4、window.name:
a、发起方页面建立一个隐藏的iframe,而且源指向接收方页面
b、接收方在本身页面经过script将须要传送的数据放入window.name里
c、发起方在iframe的onload方法里将iframe的源改成和本身在同一个域下的代理页面(由于只能是同一个域下才能访问window.name的值)
d、获取window.name的值(虽然iframe的源改变了,可是window.name的值不会变)
window.name的值差很少能够有2MB大小
5、HTML5的postMessage
a、receiverWindow.postMessage(msg, targetOrigin),receiverWindow就是对接收消息的window的引用,能够是iframe的contentWindow/window.open的返回值/window.frames中的一个;msg就是要发送的消息,string类型;targetOrigin用于限制receiverWindow的URI,包括主域名和端口,使用“*”表示无限制,可是为了安全起见仍是须要设置下,以防把消息发送给恶意的网站,若是targetOrigin的URI和receiverWindow的不符,则放弃发送消息。
b、接收方经过message事件来得到消息,而且经过event.origin的属性来验证发送方并经过event.data来得到传送的消息内容,event.source来得到发送方的window对象
6、window.opener
适用于IE6、7,也就是operner hack方法,不过貌似如今已经无论用了,只要打过微软的安全补丁.kb2497640就不能用了
a、发起方页面建立一个隐藏的iframe,而且源指向接收方页面
b、发起方页面经过iframe.contentWindow.opener = {a: function(params){...}, b: function(params){...} ...}来定义可被接收方调用的方法
c、接收方页面经过window.opener.a/window.opener.b来调用发起方定义的方法
d、接收方页面经过parent.opener = {c: function(params){...}, d: function(params){...} ...}来定义可被发起方调用的方法
e、发起方页面经过opener.c/opener.d来调用接收方定义的方法
其实原理就是重置opener对象
7、window.navigator
适用于IE6、7,貌似如今还能用,还没被补丁掉
a、发起方页面建立一个隐藏的iframe,而且源指向接收方页面
b、发起方页面经过window.navigator.a = function(params){...}; window.navigator.b = function(params){...}; 来定义被接 收方调用的方法
c、接收方页面经过window.navigator.a(params); window.navigator.b(params);来调用发起方定义的方法
d、接收方页面经过window.navigator.c = function(params){...}; window.navigator.d = function(params){...}; 来定义被发起方调用的方法
e、发起方页面经过window.navigator.c(params); window.navigator.d(params);来调用接收方定义的方法