Fork me on GitHub

同源策略与跨域

同源策略

  • 所谓同源是指2个页面要具有相同的协议,域名,端口,三者缺一不可。
  • 同源策略指的是浏览器对不同源的脚本或文本的访问进行限制,即源a下的js文件无法获取源b下的元素属性。
  • 同源策略限制的是js中XMLHttpRequest请求,以下情况不受同源策略的影响:
  • 页面中的链接,重定向,表单提交
  • 允许跨域资源的嵌入,如果要阻止iframe嵌入我们网站的资源(页面或者js等),我们可以在web服务器加上一个X-Frame-Options DENY头部来限制。

同源策略

跨域问题

前提条件是我们在WEB服务器或者服务端脚本中设置ACCESS-CONTROL-ALLOW-ORIGIN头部,如果设置了这些头部并允许某些域名跨域访问,则浏览器就会跳过同源策略的限制返回对应的内容。

AJAX跨域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# index.html
<!DOCTYPE html>
<html>
<head>
<title>test cross domain</title>
<script src="/js/jquery.js"></script>
<script src="http://www.bar.com/js/test.js"></script>
<script>
$(function(){
document.domain = 'foo.com'; //1 注释掉则会报错
var ifr = document.getElementById("testframe");
ifr.onload = function(){
var doc = ifr.contentDocument || ifr.contentWindow.document;
alert(doc.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
}
});
$.ajax("http://www.bar.com/js/test.js"); //2 报错
</script>
</head>
<body>
<h1>Test Cross Domain</h1>
<iframe id="testframe" src="http://foo.com/test.html"></iframe>
</body>
</html>

JSONP跨域

实现原理

与AJAX没多大关系,通过动态插入script标签来实现跨域资源访问。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# jsonp.html
<script type="text/javascript">
function callback(data) {
alert(data.message);
}
function addScriptTag(src){
var script = document.createElement('script');
script.src = src;
document.body.appendChild(script);
}
window.onload = function(){
addScriptTag("http://www.foo.com/js/outer.js");
}
</script>
# outer.js
callback({message:"success"});

通过动态创建script标签加载outer.js文件,然后outer.js文件返回的内容正好是一个函数调用,如此,实现了数据传递和回调过程。当然,实际的jsonp接口中,会传一个函数名过去,然后返回的数据中回调函数名就是传的函数名,回调函数的参数则是封装的json格式。

参考文章

据说帅的人都赏给博主几块钱零花钱。