在非同源情况下,共有三种行为受到限制:
(1)Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM和js对象 无法获得。
(3) AJAX 请求不能发送。
一、Cookie
Cookie 是服务器写入浏览器的一小段信息,只有同源的网页才能共享。
1.浏览器允许通过设置document.domain共享Cookie
如果A网页是http://w1.chen.com/a.html,B网页是http://w2.chen.com/b.html,那么只要设置相同的document.domain,两个网页就可以共享Cookie。
<script> document.domain = 'chen.com'; </script>
这样在A中设置一个cookie:document.cookie = 'test=yoyoyo',在B中通过document.cookie也可以访问。
注意,这种方法只适用于 Cookie 和 iframe 窗口,LocalStorage 和 IndexDB 无法通过这种方法,规避同源政策。
二、iframe
如果两个网页不同源,就不会拿到对方的DOM,像iframe窗口和window.open()打开的窗口。如果这两个窗口一级域名相同二级域名不同,使用document.domain也可以拿到dom
1.window.name
window.name属性的独特之处:只要在同一个窗口里,name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)。缺点是必须监听子窗口window.name的值,影响网页性能。
2.window.postMessage
HTML5引入了一个全新的API:跨文档通信 API(Cross-document messaging)。这个API为window对象添加了一个window.postMessage方法,允许跨窗口通信。解决了以下问题:
a.) 页面和其打开的新窗口(window.open)的数据传递
b.) 多窗口之间消息传递
c.) 页面与嵌套的iframe消息传递
d.) 上面三个场景的跨域数据传递
用法自行百度。
通过这种方法,读写其他窗口的LocalStorage也成为可能。
三、AJAX
在同源中AJAX请求只能发给同源的网址,否则会报错。
我们可以架设服务器代理(浏览器请求同源服务器,再由后者请求外部服务),还有以下几种方式:
1.JSONP
script标签src属性中的链接可以访问跨域的js脚本,利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。
其基本思想是,网页通过动态的添加script标签,向服务器请求JSON数据,服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
<script> var script = document.createElement('script'); script.type = 'text/javascript'; // 传参并指定回调执行函数为onBack script.src = 'http://www.example.com:8080/login?user=admin&callback=onBack'; document.head.appendChild(script); // 回调执行函数 function onBack(res) { alert(JSON.stringify(res)); } </script>
上面代码中通过动态添加<script>元素,向服务器example.com发送请求,有一个回调参数callback用来指定回调函数名字,服务器接收到请求后,会将数据放在回调函数的参数位置返回。
服务端返回如下
onBack({"status": true, "user": "admin"})
所以JSONP将访问跨域请求变成了执行远程JS代码,服务端不再返回JSON格式的数据,而是返回了一段将JSON数据作为传入参数的函数执行代码。
但jsonp只能发送get请求
2.WebSocket
WebSocket是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现。原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。
3.CORS
CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求的根本解决方法。实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
详情请戳:http://www.ruanyifeng.com/blog/2016/04/cors.html
借鉴于:https://www.cnblogs.com/roam/p/7520433.html,http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html