• springboot解决CORS跨域的三种方式


    目录

    一、实现WebMvcConfigurer接口

    二、实现filter过滤器方式

    三、注解@CrossOrigin

    四、实战

    五、cookie的跨域

    SpringBoot 2.6及以上版本

    SpringBoot 2.6以下版本


    一、实现WebMvcConfigurer接口

    1. @Configuration
    2. public class WebConfig implements WebMvcConfigurer {
    3. /**
    4. * 添加跨域支持
    5. */
    6. @Override
    7. public void addCorsMappings(CorsRegistry registry) {
    8. // 允许跨域访问的路径 '/**'表示应用的所有方法
    9. registry.addMapping("/**")
    10. // 允许跨域访问的来源 '*'表示所有域名来源
    11. .allowedOriginPatterns("*")
    12. // .allowedOrigins("*") // 允许跨域访问的来源 SpringBoot2.4.0之前的版本
    13. // 允许跨域请求的方法 '*'表示所有
    14. .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
    15. // 是否允许发送cookie true-允许 false-不允许 默认false。对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json,这个值只能设为true
    16. .allowCredentials(true)
    17. // 预检间隔时间1小时,单位为秒。指定本次预检请求的有效期,在有效期间,不用发出另一条预检请求。
    18. // 浏览器发出CORS简单请求,只需要在头信息之中增加一个Origin字段
    19. // 浏览器发出CORS非简单请求,会在正式通信之前,增加一次OPTIONS查询请求,称为"预检"请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
    20. .maxAge(3600)
    21. // 允许跨域请求可携带的header,'*'表所有header头。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定
    22. .allowedHeaders("*");
    23. }
    24. }

    二、实现filter过滤器方式

    1. @WebFilter
    2. @Configuration
    3. public class CorsFilter implements Filter {
    4. @Override
    5. public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    6. HttpServletResponse response = (HttpServletResponse) res;
    7. response.setHeader("Access-Control-Allow-Origin", "*");
    8. response.setHeader("Access-Control-Allow-Credentials", "true");
    9. response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT");
    10. response.setHeader("Access-Control-Max-Age", "3600");
    11. response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    12. chain.doFilter(req, res);
    13. }
    14. }

    三、注解@CrossOrigin

    @CrossOrigin(originPatterns = "*", allowCredentials = "true")

    @CrossOrigin可配置在方法上,也可配置在类上。 

    四、实战

    创建两个普通的SpringBoot项目A、B,A配置8081端口,B配置8082端口。

    在A的resources/static目录下创建一个html文件index.html:

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>Title</title>
    6. </head>
    7. <!-- jquery库可百度jquery cdn -->
    8. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
    9. <script>
    10. function btnClick() {
    11. $.get('http://localhost:8082/hello/hello', function (msg) {
    12. $("#app").html(msg);
    13. });
    14. }
    15. function btnClick2() {
    16. $.post('http://localhost:8082/hello/hello', function (msg) {
    17. $("#app").html(msg);
    18. });
    19. }
    20. </script>
    21. <body>
    22. <div id="app"></div>
    23. <input type="button" onclick="btnClick()" value="get_button">
    24. <input type="button" onclick="btnClick2()" value="post_button">
    25. </body>
    26. </html>

    B提供2个web接口:

    1. @RestController
    2. @RequestMapping("/hello")
    3. public class HelloController {
    4. // @CrossOrigin(originPatterns = "*", allowCredentials = "true")
    5. @GetMapping("/hello")
    6. public String hello() {
    7. System.out.println("get hello");
    8. return "get hello";
    9. }
    10. // @CrossOrigin(originPatterns = "*", allowCredentials = "true")
    11. @PostMapping("/hello")
    12. public String hello2() {
    13. System.out.println("post hello");
    14. return "post hello";
    15. }
    16. }

    分别启动A、B服务,浏览器访问A的index.html,点击按钮,浏览器控制台报错如下:

    http://localhost:8081/index.html
    Access to XMLHttpRequest at 'http://localhost:8082/hello/hello' from origin 'http://localhost:8081' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

     为B项目使用方式一,添加跨域支持,重启,再次点击按钮,可正常访问,观察响应头多了支持跨域的信息:

    五、cookie的跨域

    从Chrome51开始,浏览器cookie添加了一个新属性SameSite,以防止 CSRF 攻击和用户跟踪。

    SameSite可取值:Strict、Lax、None。

    Strict最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。

    Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。导航到目标 URL 的 GET 请求仅包括三种情况:链接、预加载请求和 GET 表单。

    网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。

    SpringBoot 2.6及以上版本

    可使用配置:

    1. server.servlet.session.cookie.same-site=none
    2. server.servlet.session.cookie.secure=true

    SpringBoot 2.6以下版本

    如果使用 Tomcat 作为服务器,则可以通过以下配置设置会话 cookie 的 SameSite 属性。

    server.servlet.session.cookie.secure=true
    1. @Configuration
    2. public class TomcatCookieConfig {
    3. @Bean
    4. public TomcatContextCustomizer sameSiteCookiesConfig() {
    5. return context -> {
    6. final Rfc6265CookieProcessor cookieProcessor = new Rfc6265CookieProcessor();
    7. // SameSite
    8. cookieProcessor.setSameSiteCookies(SameSiteCookies.NONE.getValue());
    9. context.setCookieProcessor(cookieProcessor);
    10. };
    11. }
    12. }

    如果您使用的是 Spring-Session,那么您可以使用以下配置来设置 cookie 的 SameSite 属性。

    1. <dependency>
    2. <groupId>org.springframework.session</groupId>
    3. <artifactId>spring-session-core</artifactId>
    4. </dependency>
    1. @Configuration
    2. public class SpringSessionConfiguration {
    3. @Bean
    4. public CookieSerializer cookieSerializer() {
    5. DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
    6. // Strict-严格模式 Lax-松懈模式 None-无
    7. cookieSerializer.setSameSite("None");
    8. cookieSerializer.setUseSecureCookie(true);
    9. return cookieSerializer;
    10. }
    11. }

    参考:https://www.cnblogs.com/javastack/p/14255114.html

  • 相关阅读:
    【树莓派不吃灰】Linux篇⑩ 学习例行性工作排程(核心概念)
    设计模式-03-建造者模式
    python毕业设计作品基于django框架新闻信息管理系统毕设成品(4)开题报告
    【wvp+ GiVideoCall】 三种主要应用场景
    v73.结构
    JavaScript高级 js语言通识
    SpringBoot:分页Pageable最大size配置
    数据结构:循环队列
    易基因:细菌微生物基因表达调控表观研究方案|原核三代甲基化+转录组
    测试架构师如何落地性能测试方案(一)
  • 原文地址:https://blog.csdn.net/yzh_1346983557/article/details/125434393