浏览器同源策略
含义
所谓同源策略,指的是浏览器对不同源的脚本或者文本的访问方式进行的限制。比如源a的js不能读取或设置引入的源b的元素属性。
那么先定义下什么是同源,所谓同源,就是指两个页面具有相同的协议,主机(也常说域名),端口,三个要素缺一不可。
同源是指
* 协议相同
* 域名相同
* 端口相同
目的
同源策略的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。浏览器同时访问2个跨域网站,如果A可以访问B网站的信息,那么就数据随时会被别人窃取。
限制范围
随着互联网的发展,"同源政策"越来越严格。目前,如果非同源,共有三种行为受到限制。
* Cookie、LocalStorage和IndexDB无法读取。
* DOM 无法获取。
* AJAX 请求不能发送。
跨域的几种解决方法
Cookie
Cookie 是服务器写入浏览器的一小段信息,只有同源的网页才能共享。但是,两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置document.domain
共享 Cookie。
举例来说,A网页是http://w1.example.com/a.html
,B网页是http://w2.example.com/b.html
,那么只要设置相同的document.domain
,两个网页就可以共享Cookie。
document.domain = 'example.com';
现在,A网页通过脚本设置一个Cookie。
document.cookie = "test1=hello";
B网页就可以读到这个 Cookie。
var allCookie = document.cookie;
注意,这种方法只适用于 Cookie 和 iframe 窗口,LocalStorage 和 IndexDB 无法通过这种方法,规避同源政策,而要使用其他方法规避。
也可以通过后台服务器端设置Cookie的时候,指定Cookie的所属域名为一级域名,比如.example.com
。
Set-Cookie: key=value; domain=.example.com; path=/
iframe
通过下面2个方法,去获取不同源的iframe里面的DOM或者iframe里面获取外面的DOM,都会跨域
document.getElementById("myIFrame").contentWindow.document
window.parent.document.body
解决方法和Cookie一样,如果两个窗口一级域名相同,只是二级域名不同,那么设置上一节介绍的document.domain
属性,就可以规避同源政策,拿到DOM。
这3种方法在这里就不过多描叙了,就是通过url的hash值和iframe里面通信
* 片段识别符(fragment identifier)
* window.name
* 跨文档通信API(Cross-document messaging)
JSONP
它的基本思想是,网页通过添加一个<script>
元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
首先,网页动态插入<script>
元素,由它向跨源网址发出请求。
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function () {
addScriptTag('http://example.com/ip?callback=foo');
}
function foo(data) {
console.log('Your public IP address is: ' + data.ip);
};
上面代码通过动态添加<script>
元素,向服务器example.com
发出请求。注意,该请求的查询字符串有一个callback
参数,用来指定回调函数的名字,这对于JSOPNP是必需的。
服务器收到这个请求以后,会将数据放在回调函数的参数位置返回。
foo({
"ip": "8.8.8.8"
});
由于<script>
元素请求的脚本,直接作为代码运行。这时,只要浏览器定义了foo
函数,该函数就会立即调用。作为参数的JSON数据被视为JavaScript对象,而不是字符串,因此避免了使用JSON.parse
的步骤。
WebSocket
WebSocket是一种通信协议,使用ws://
(非加密)和wss://
(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。
网友评论