先看概念,什么是跨域:协议、域名、端口中有任何一个不同,它们之间要通信就叫跨域。
情形 | 是否允许通信 |
同一域名下 | 是 |
同一域名下不同文件夹 | 是 |
同一域名、不同端口 | 否 |
同一域名、不同协议 | 否 |
域名和域名对应ip | 否 |
主域名相同、子域名不同 | 否 |
不同域名 | 否 |
常用的跨域方式有2种:CROS(跨域资源共享Cross-Origin Resource Sharing)、JSONP
CROS:服务器端对于CORS
的支持,主要就是通过设置Access-Control-Allow-Origin
来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。该设置只被现代浏览器支持
JSONP:实际是对跨域行为的hack手段,实现原理和加载js是一个道理,所以只能实现get请求的jsonp.
在js中,我们直接用XMLHttpRequest
请求不同域上的数据时,是不可以的。但是,在页面上引入不同域上的js脚本文件却是可以的,jsonp正是利用这个特性来实现的。
CORS和JSONP对比
CORS与JSONP相比,无疑更为先进、方便和可靠。
1、 JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。
3、 JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS)。
通过修改document.domain来跨子域
这种方式比较适合父域名相同而子域名不同的情况,通过将document.domain修改成为相同的父域名可以实现互相通信,比如:
parent.a.com/parent.html页面里有个iframe,iframe的src指向child.a.com/child.html,正常情况下这两个页面是无法实现通信的,
但是只要在parent.html和child.html里分别设置document.domain="a.com",这两个页面即可实现互相通信
(但要注意的是,document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域)
使用window.name来进行跨域
window
对象有个name
属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name
的,
每个页面对window.name
都有读写的权限,window.name
是持久存在一个窗口载入过的所有页面中的
使用HTML5的window.postMessage方法跨域
window.postMessage(message,targetOrigin)
方法是html5
新引进的特性,可以使用它来向其它的window
对象发送消息,
无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera
等浏览器都已经支持window.postMessage
方法。