1.浏览器的同源策略
1) 定义: 请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同.
浏览器中的地址:http://roger.com:8080/demo/a.html | ||
---|---|---|
请求地址 | 形式 | 结果 |
http://roger.com:8080/test/b.html | 同一域名,同一端口号,同一协议 不同文件夹 | 成功 |
http://roger.com:8080/demo/c.html | 同一域名,同一端口号,同一协议 同一文件夹 | 成功 |
http://roger.com:8090/demo/a.html | 同一域名,不同端口号,同一协议 | 失败 |
http://roger.cn:8080/demo/a.html | 不同域名,同一端口号,同一协议 | 失败 |
https://roger.com:8080/demo/a.html | 同一域名,同一端口号,不同协议 | 失败 |
2)同源策略限制一下几种行为
A:Cookie、LocalStorage 和 IndexDB 无法读取
B:DOM 和 JS 对象无法获取
C:Ajax请求无法发送
2.跨域问题
1) 从浏览器的同源策略可以看出来,跨域问题不是服务器问题,是浏览器问题。
2) 跨域问题,并不是浏览器限制了发起跨站请求,而是跨站请求可以正常发送,但是返回结果被浏览器拦截了;
最好的例子就是CRSF跨站攻击原理,无论是否跨域,请求已经发送到了后端服务器!
因此,只要在服务器端配置为所有域都可以访问,那么不在服务器端运行的html就可以完成http请求。
3.SpringMVC跨域解决方案
(一)第一种解决方案,使用JSONP
1)JSONP 原理
就是当服务器接受到名为jsonp
或者callback
的参数时,返回Content-Type: application/javascript
的结果,从而避免浏览器的同源策略检测。
2) 实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="http://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
function println(data) {
console.log(data);
console.log('print');
}
function jsonp_test() {
$.ajax({
type: "get",
url: "http://localhost:8080/roger/getData",
dataType: "jsonp",
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
jsonpCallback: "println", //返回后调用的处理函数
error: function () { //请求出错的处理
alert("请求出错");
}
});
}
</script>
</head>
<body onload="jsonp_test()">
</body>
</html>
3) jsonp缺点:只能解决 GET类型请求的跨域问题
(二)第二种解决方案,使用CORS协议
1) CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
2) CORS需要浏览器和服务器同时支持。
A:所有浏览器都支持该功能,IE浏览器不能低于IE10。
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。 对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
B:实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。