CORS跨域

2018-07-27  本文已影响34人  一个菜鸟JAVA
什么是跨域

做web开发的时候,可能会遇到Origin null is not allowed by Access-Control-Allow-Origin这个错误。这就是因为你的请求跨域了,然后浏览器把服务器返回的结果拦截了。首要要明白的一点是,这是浏览器的行为,服务端已经响应请求了,而浏览器因为同源策略原因,把请求拦截了。那什么是同源策略呢?

同源策略

在javascript中,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。
那么什么叫相同域,什么叫不同的域呢?
当两个域具有相同的协议(如http), 相同的端口(如80),相同的host(如www.example.org),那么我们就可以认为它们是相同的域。例子看下面的列表

URL1 URL2 说明 是否跨域
http://www.xxx.com/a http://www.xxx.com/b 同一域名
http://www.xxx.com:8080/a http://www.xxx.com/a 不同端口
https://www.xxx.com/a http://www.xxx.com/a 协议不同
https://www.xxx.com/a http://192.168.1.1/a 域名和域名对应ip
https://www.xxx.com/a https://api.xxx.com/a 主域相同,子域不同
https://www.xxx.com/a https://xxx.com/a 同一域名,不同二级域名(同上)
https://www.xxx.com/a https://yyy.com/a 不同域名
CORS

上面说了有跨域的问题的存在,那现在该如何解决呢?
解决的方式有很多种,例如jsonp,CORS等等很多。这里我只说使用CORS.
CORS全名Cross-origin resource sharing(跨来源资源共享),它的原理就是服务端在响应的请求头中添加
Access-Control-Allow头,告诉浏览器这个资源什么域名,什么请求方式请求,我允许它跨域请求。有的人之前一直误解这个头是添加在请求头中,这个想法是错误的。因为如果是请求方自己告诉自己的,那还有什么意义。
在SpringMVC中,可以通过在Controller上添加@CORS注解来实现接口支持跨域。

示例

后端代码

@RestController
public class CorsTestController {
    @GetMapping("/cors/test")
    public String corsTest(){
        return "success";
    }
}

前端代码,前端就是点击按钮请求服务器,然后把结果展示出来。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
    <script type="application/javascript">
        function submit() {
            $.ajax({
                url:"http://127.0.0.1:8090/cors/test",
                success:function(result){
                    alert(result)
                }
            });
        }
    </script>
</head>
<body>
<div>
    <button onclick="submit()">请求</button>
</div>
</body>
</html>

结果

请求失败,因为跨域了
修改服务端代码,在接口上加上@CrossOrigin,再次请求
@CrossOrigin
    @GetMapping("/cors/test")
    public String corsTest(){
        return "success";
    }
请求成功
仔细看两场请求服务器响应的结果,可以发现,第二次服务器响应头多了一些东西,主要就是红框的地方,这个地方就是服务器在响应头上加上了Access-Control-Allow-Origin: *,这句话简单翻译就是:权限-控制-允许-来源:全部
当然,如果只是加上@CrossOrigin,默认的就是所有的域,但是实际生产中,我们可以只想支持一些指定的,所有你还可以指定哪些域名可以访问。
上一篇下一篇

猜你喜欢

热点阅读