浏览器的同源策略的目的是为了确保用户的信息安全,防止用户的数据被窃取。
每当客户端向服务器端发送请求时,请求都会携带cookie发送给服务器,cookie中包含着用户信息(这里又涉及到cookie的知识,cookie的作用有哪些呢?),
如果没有同源限制,用户的信息就可以被随便发送到某个服务器。
什么是同源呢?
协议+端口+域名 都相同的页面就是同源的。
浏览器的同源策略有哪些限制呢?
不同源之间的页面有三个限制:
1、cookie、localStorage、indexDB不能共享
2、dom不能获取
3、ajax请求不能发送
什么时候需要规避同源限制呢?
不同的源的网页之间需要相互跳转链接,有时甚至还要传递数据。
比如实际场景中的一个例子,旧项目因为写的太烂,我们建了一个新项目准备去重构旧的项目,但是因为现在业务太多,我们暂时没有时间将旧项目中的代码全部迁移到新的项目里面,我们不可能再在旧的项目里面去写新的需求,所以新的需求我们要在新的项目里面做,然后在完全重构好旧的项目到新的项目里面之前,我们都要将新写的需求的模块用iframe的方式嵌入到旧项目里。两个不同的项目的域名和端口都是不一样的,所以需要对跨域进行处理。
如何规避同源策略呢?
1、规避cookie不能共享的问题
cookie只能在同源的网页中共享,如果二级域名不同,一级域名相同,可以给网页设置document.domain的值为这个相同的一级域名,cookie就可以共享
(可以详细了解cookie的特点)
2、规避不能拿到dom
比如一个页面中通过iframe嵌入另一页面,且这两个页面是不同源的,那么如果想在父窗口获取子窗口中dom,是不能拿到的。
一级域名相同,二级域名不同,可以通过设置document.domain来解决跨域问题。
完全不同的源解决跨域窗口通信问题:
1、片段标识符
将需要跨窗口传递的值设置在url的#后面,因为改变url的#的值时,页面不会刷新。
在接受数据的子页面,通过window.onhaschange事件监听来获取到数据。
2、window.name
无论是否同源,只要是在同一窗口,网页就可以读取到window.name。
容量大可以放很长的字符串。
但是需要监听子页面的window.name的变化,影响网页性能。
3、postMessage(跨文档通信api)
通过postMessage给指定域的网页发送消息,接受数据的页面通过message事件去获取消息。
这个方法可以还可以跨域访问localstroge中的数据。
3、Ajax不能跨域请求
1、JSONP
jsonp的本质是利用script标签去跳转url,因为script标签没有同源的限制,然后在url上带上一个函数回调参数。数据通过这个函数回调参数来传递。
2、Websocket
利用websocket来实现通信,因为websocket协议没有同源策略的限制。
3、Cors
通过跨域资源分享,在服务器端响应头部设置跨域的范围。
cors和jsonp的区别是,jsonp只能发get请求,但是cors支持任何类型的请求。
参考资料:
同源策略及规避策略:http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
postMessage: https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage