问答
什么是同源策略
- 源:如果两个页面的协议,端口和域名是相同的,则两个页面具有相同的源。
- 同源策略限制从一个源加载的文档或脚本与另一个不同的源的资源进行交互。
- 即一个页面不能调用另一个不同源中的脚本。(可以引用,例如src,但不能读写)
什么是跨域?跨域有几种实现形式
- 跨域:从一个页面去请求读或者写另一个页面的资源,突破同源策略的限制。
- 跨域的几种实现形式:
- 降域:仅限主域名相同子域名不同的两个页面交互,可以通过设置
document.damain
属性来使两个页面的域名相同,从而避开同源策略,实现跨域。
- 降域:仅限主域名相同子域名不同的两个页面交互,可以通过设置
- JSONP:即json with padding,这种方式可以实现跨域
- CORS:即Cross-Origin Resource Sharing 跨域资源共享,通过增加一个新的响应头实现跨域。
- window.postMessage : HTML5中新规定的属性,也可以实现跨域
- 其他方式,利用hash或利用window.name,不建议使用
jsonp 的原理是什么
- 我们知道script标签中的src属性可以引用别的源的脚本,我们可以利用这个特性,在网页中动态的创建添加script标签,请求需要访问的页面资源的url,服务器将数据放在一个指定名字的回调函数中给传回来,由于网页已经定义的该函数,参数被返回后,便会立即执行。
CORS是什么
- CORS的全称是Cross-Origin Resources Sharing,它允许浏览器向跨源服务器,发出请求,从而克服了AJAX只能同源使用的限制,支持现代浏览器,IE支持10以上。
- 实现方式很简单,当你使用 XMLHttpRequest 发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin; 浏览器判断该相应头中是否包含 Origin 的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。所以 CORS 的表象是让你觉得它与同源的 ajax 请求没啥区别,代码完全一样。
练习
本地搭建服务器,演示同源策略
- 首先使用XAMPP搭建服务器,然后修改hosts,在hosts的最后添加两行代码:
127.0.0.1 reedsun.com
127.0.0.1 b.com
这样当我访问reedsun.com和b.com都会定向到我的本地服务器。
- 给index.html和main.js添加如下代码
// index.html
<script src="http://b.com/main.js"></script>
// main.js
alert("我是b.com");
发现成功:
说明引用不受同源策略的影响。
- 我们更改index.html的代码:
<script>
$.get("//b.com/main.js");
</script>
发现并没有运行b.com/main.js,查看报错,发现是同源策略阻止了a.com/index.html的ajax行为:
至少使用一种方式解决跨域问题
- 创建一个index.html和一个data.php,我们打算用
reedsun.com/index.html
访问b.com/data.php
里的数据,我打算使用CURS方法。
// index.html
<script>
document.damain = "b.com";
$.get("//b.com/data.php", function(response){
console.log(response);
});
</script>
// data.php
<?php
echo "我是 b.com/data.php,当你看到这条提示,说明你已经跨域成功了";
?>
- 刷新页面,没有得到数据,提示被同源策略阻止:
- 将data.php加上响应头:
// data.php
<?php
header("Content-type: ");
header('Access-Control-Allow-Origin: http://reedsun.com');
echo "我是 b.com/data.php,当你看到这条提示,说明你已经跨域成功了";
?>
- 再次刷新页面,发现响应成功: