• 峰哥说技术:18-Spring Boot通过CORS实现跨域请求


    Spring Boot深度课程系列

    峰哥说技术—2020庚子年重磅推出、战胜病毒、我们在行动

    18  峰哥说技术:Spring Boot通过CORS实现跨域请求

    对于跨域,必须要说是浏览器的同源策略。同源策略是由Netscape提出的一个著名的安全策略,它是浏览器最核心也最基本的安全功能,现在所有支持JavaScript的浏览器都会使用这个策略。

    所谓同源是指协议、域名以及端口要相同。同源策略是基于安全方面的考虑提出来的,这个策略本身没问题,但是我们在实际开发中,由于各种原因又经常有跨域的需求,传统的跨域方案是JSONP,JSONP虽然能解决跨域但是有一个很大的局限性,那就是只支持GET请求,不支持其他类型的请求。

    我们说的CORS(跨域源资源共享)(CORS,Cross-origin resource sharing)是一个W3C标准,它是一份浏览器技术的规范,提供了Web服务从不同网域传来沙盒脚本的方法,以避开浏览器的同源策略,这是JSONP模式的现代版。
    Spring框架中,对于CORS也提供了相应的解决方案,下面我们看看Spring Boot中如何实现CORS。

    步骤:

    1)创建Spring Boot项目chapter04-server个,添加web依赖。同时在Application.properties中配置端口。

    server.port=8080

    2)创建BookController,编写2个测试接口。

    @RestController
    @RequestMapping("/book")
    public class BookController {
        @PostMapping("/")
        public String addBook(String name){
            return "添加"+name;
        }
        @DeleteMapping("/{bookId}")
        public String deleteBook(@PathVariable Integer bookId){
            return "删除书籍:"+bookId;
        }
    }

    3)配置在接口方法上配置跨域。

    @RestController
    @RequestMapping("/book")
    public class BookController {
        @PostMapping("/")
        @CrossOrigin(value = "http://localhost:8081",maxAge = 1800,allowedHeaders = "*")
        public String addBook(String name){
            return "添加"+name;
        }
        @DeleteMapping("/{bookId}")
        @CrossOrigin(value = "http://localhost:8081",maxAge = 1800,allowedHeaders = "*")
        public String deleteBook(@PathVariable Integer bookId){
            return "删除书籍:"+bookId;
        }
    }

    4)创建另一个Spring Boot项目chapter04-client,添加web依赖。端口号为8081,工程结构如图:

     

    5)chapter04-client的static中添加index.html页面。添加两个按钮,分别是添加图书和删除图书,发送Ajax请求。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="jquery-1.12.4.js"></script>
    </head>
    <body>
        <input type="button" onclick="insertBook()" value="添加图书"> <br>
        <input type="button" onclick="deleteBook()" value="删除图书">
        <div id="div1"></div>
    </body>
    <script type="application/javascript">
        function insertBook() {
            $.ajax({
                url:"http://localhost:8080/book/",
                data:{"name":"红楼梦"},
                type:"post",
                success:function (msg) {
                   $("#div1").html(msg);
                }
            })
        }
        function deleteBook() {
            $.ajax({
                url:"http://localhost:8080/book/90",
                type:"delete",
                success:function (msg) {
                    $("#div1").html(msg);
                }
            })
        }
    </script>
    </html>

    6)测试:在浏览器输入:http://localhost:8081/index.html

     

    浏览器调试分析:

     

    这里的Access-Control-Allow-Origin: http://localhost:8081表示服务器愿意愿意接收来自http://localhost:8081的请求,拿到这个信息后,浏览器就不会再去限制本次请求的跨域了。

    在服务器端,如果每一个方法上都去加注解未免太麻烦了,在Spring Boot中,还可以通过全局配置一次性解决这个问题,全局配置只需要在配置类中重写addCorsMappings方法即可,如下:

    步骤:

    1)注释方法上的@CrossOrigin注解。

    2)编写WebMvcConfig配置类,实现接口WebMvcConfigurer,实现方法public void addCorsMappings(CorsRegistry registry)

    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/book/**")
                    .allowedHeaders("*")
                    .allowedMethods("*")
                    .allowedOrigins("http://localhost:8081")
                    .maxAge(1800);
        }
    }

    addMapping("/book/**")表示本应用的所有方法都会去处理跨域请求,allowedMethods表示允许通过的请求方法,默认是GET、POST和HEAD,*表示支持所有的请求方法,allowedHeaders则表示允许的请求头。*表示所有的请求头。allowedOrigins("http://localhost:8081")表示支持的域。经过这样的配置之后,就不必在每个方法上单独配置跨域了。

    了解了整个CORS的工作过程之后,我们通过Ajax发送跨域请求,虽然用户体验提高了,但是也有潜在的威胁存在,常见的就是CSRF(Cross-site request forgery)跨站请求伪造。跨站请求伪造也被称为one-click attack 或者 session riding,通常缩写为CSRF或者XSRF,是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。

    基于此,浏览器在实际操作中,会对请求进行分类,分为简单请求,预先请求,带凭证的请求等,预先请求会首先发送一个options探测请求,和浏览器进行协商是否接受请求。默认情况下跨域请求是不需要凭证的,但是服务端可以配置要求客户端提供凭证,这样就可以有效避免csrf攻击。

  • 相关阅读:
    Bootstrap
    继承与多态
    面对对象与封装
    antd表格排序
    样式文本过长用...显示的时候,用弹框来显示文本(react为例)
    锚点
    树形结构的搜索,只显示搜索内容
    fetch不携带cookie
    antd 给select下拉框添加懒加载
    post方法下载文件
  • 原文地址:https://www.cnblogs.com/027kgc/p/12502274.html
Copyright © 2020-2023  润新知