1、什么是跨域
理解跨域首先必须要了解同源策略。
同源策略:是浏览器上为安全性考虑实施的非常重要的安全策略。
何谓同源: URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。
同源的判定:
以http://www.example.com/dir/page.html
为例,以下表格指出了不同形式的链接是否与其同源:(原因里未申明不同的属性即说明其与例子里的原链接对应的属性相同)
链接 | 结果 | 原因 |
---|---|---|
http:// www.example.com /dir/page2.html | 是 | 同协议同域名同端口 |
http:// www.example.com /dir2/other.html | 是 | 同协议同域名同端口 |
http://user:pwd@ www.example.com /dir2/other.html | 是 | 同协议同域名同端口 |
http://www.example.com: 81 /dir/other.html | 否 | 端口不同 |
https ://www.example.com/dir/other.html | 否 | 协议不同端口不同 |
http:// en.example.com /dir/other.html | 否 | 域名不同 |
http:// example.com /dir/other.html | 否 | 域名不同(要求精确匹配) |
http:// v2.www.example.com /dir/other.html | 否 | 域名不同(要求精确匹配) |
http://www.example.com: 80 /dir/other.html | 不确定 | 取决于浏览器的实现方式 |
不同源之间的访问即为跨域。
2、同源政策的目的
同源策略的目的是为了保证用户信息的安全。防止恶意的网站盗取数据。
设想这样一个情景:A网站是一家银行,用户登录以后,又去浏览其他的网站B,如果网站B可以读取A网站的Cookie,会发生什么问题?
显然,如果Cookie包含隐私(比如存款总额),这些信息就会泄露,更可怕的是,Cookie往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒用户,为所欲为。因为浏览器同时还规定,提交表单不受同源策略的限制。
由此可见,“同源政策”的必要性,否则Cookie可以共享,互联网就毫无安全可言了。
3、实现跨域访问的方式之一
首先写一个简单的H5页面test.htm
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TEST CSRF</title>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>
<script type="text/javascript">
var url="http://localhost:7001/account/login";
$.ajax({
url:url,
type:'POST',
data:'userId=root&password=root',
success:function (data) {
alert(data);
},
error:function (xhr,status,error) {
alert(status);
alert(error);
}
});
</script>
</head>
<body>
</body>
</html>
把这个页面放在tomcat上,启动tomcat,服务端口设为8080,使页面源与请求的资源源不同源。
http://localhost:7001/account/login是我本地的一个Spring cloud项目提供的服务接口。
@PostMapping("/account/login")
@ResponseBody
public ResultModel<String> login(
HttpServletResponse response,
HttpServletRequest request,
@RequestParam String userId,
@RequestParam String password ){
//response.setHeader("Access-Control-Allow-Origin","*");
return this.accountService.login(response, userId, password);
}
首先把response.setHeader("Access-Control-Allow-Origin","*"); 注掉
两个应用同时启动,浏览器打开http://localhost:8080/test.htm,结果如下:
浏览器F12,控制台输出如下:
为了证明浏览器确实发出请求了,并且接收到数据了,用fidller抓包来分析一下,抓包结果如下:
请求报文
响应报文
真相大白,浏览器确实发出请求,并且接收到数据了。但是因为响应头没有"Access-Control-Allow-Origin",所以拒绝把数据返回给前端。
响应头
我们把response.setHeader("Access-Control-Allow-Origin","*"); 的注释解开,再请求一下,结果如下:
现在响应头多了一行,再看H5前端,成功拿到数据
更多的跨域问题请参考以下链接
本文部分内容转自:
https://blog.csdn.net/menghuanzhiming/article/details/78980761
https://blog.csdn.net/wonking666/article/details/79159180
https://blog.csdn.net/bu1bu2/article/details/54138867
https://blog.csdn.net/fanlei5458/article/details/81007366
https://blog.csdn.net/brycegao321/article/details/52841626
https://blog.csdn.net/zmx729618/article/details/53319383
https://blog.csdn.net/u013084331/article/details/51114288