什么是域?
协议、域名、端口三者组成一个域,三者之中有其一不同,亦被称之为不同域,不同域之间的请求与调用,我们称之为跨域。
什么是同源策略?
浏览器的同源策略是为了安全考虑,可以理解同域就是同源。同源策略规定,不同的域之间不能进行一下三种操作:
1、cookie、localStorage 和 indexDB;
2、DOM 获取
3、AJAX 请求
跨域方案:
1、跨域资源共享( CORS )
2、jsonp
3、服务器代理
4、document.domain(只能实现跨子域)
5、location.hash
6、postMessage
具体实现:
1、跨域资源共享
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。CORS 需要客户端和服务器同时支持。目前,所有浏览器都支持该机制,IE浏览器不能低于IE10。具体请参考阮一峰老师的博客:http://www.ruanyifeng.com/blog/2016/04/cors.html
2、jsonp
通常为了减轻web服务器的负载,我们把js、css,img等静态资源分离到另一*立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许,基于此原理,我们可以通过动态创建script,再请求一个带参网址实现跨域通信。
// 定义一个fun函数 function fun(data) { console.log(data); }; // 创建一个脚本,并且告诉后端回调函数名叫fun var body = document.getElementsByTagName('body')[0]; var script = document.gerElement('script'); script.type = 'text/javasctipt'; script.src = 'demo.js?callback=fun'; body.appendChild(script);
返回的js脚本,直接会执行。所以就执行了事先定义好的fun函数了,并且把数据传入了进来。
fun({"name": "name"})
注意:jsonp只能实现get请求,因为callback只能写在url后面。
3、服务器代理
浏览器有跨域限制,但是服务器不存在跨域问题,所以可以由服务器请求所要域的资源再返回给客户端。
例如,我们在开发一个项目初期,前后端是分离的,我们前端项目在访问 http://localhost:8080/getDetail 接口时,本地是没有这个接口的。我会在nginx中把这个接口的地址代理转发到后端同事的ip地址中 http://xx.xxx.xx.xx:8888/getDetail,这样就实现了跨域访问。
4、document.domain
对于主域名相同,而子域名不同的情况,可以使用document.domain来跨域。这种方式非常适用于iframe跨域的情况,直接看例子吧 比如a页面地址为 http://a.yourhost.com b页面为 http://b.yourhost.com。 这样就可以通过分别给两个页面设置 document.domain = http://yourhost.com 来实现跨域。 之后,就可以通过 parent 或者 window[‘iframename’]等方式去拿到iframe的window对象了。
5、location.hash
location.hash方式跨域,是子框架具有修改父框架src的hash值,通过这个属性进行传递数据,且更改hash值,页面不会刷新。但是传递的数据的字节数是有限的。
6、postMessage
信息传递除了客户端与服务器之前的传递,还存在以下几个问题:
- 页面和新开的窗口的数据交互。
- 多窗口之间的数据交互。
- 页面与所嵌套的iframe之间的信息传递。
window.postMessage是一个HTML5的api,允许两个窗口之间进行跨域发送消息。这个应该就是以后解决dom跨域通用方法了