SpringBoot:解决前后端请求跨域问题(详细教程)

文章目录
  • 一、前言
  • 二、解决方式
    • [2.1 使用 @CrossOrigin 注解(简单方便,适用于单个或少量接口)](#2.1 使用 @CrossOrigin 注解(简单方便,适用于单个或少量接口))
    • [2.2 全局配置跨域(适用于整个项目中大量接口都需要跨域的情况)](#2.2 全局配置跨域(适用于整个项目中大量接口都需要跨域的情况))
    • [2.3 使用过滤器来处理跨域(更底层的实现方式,灵活性高但代码相对复杂一点)](#2.3 使用过滤器来处理跨域(更底层的实现方式,灵活性高但代码相对复杂一点))
  • 三、结语

一、前言

在前后端交互的项目中,首先要解决的就是跨域问题 ,这个问题是由于浏览器的同源策略 导致的,这种策略是一种安全机制,它要求网页的协议、域名以及端口都完全相同,才允许一个域下的网页去访问另一个域的资源,只要这三者中有一个不同,就会产生跨域的情况。具体如下:


二、解决方式

以下是几种在 Spring Boot 中解决跨域问题的常见方式:

2.1 使用 @CrossOrigin 注解(简单方便,适用于单个或少量接口)

@CrossOrigin 注解是 Spring 框架提供的用于处理跨域请求的一种便捷方式,通过在控制器类或者具体的方法上添加该注解,来告知 Spring 允许来自特定源的跨域请求,它会在响应头中自动添加相应的跨域相关的 HTTP 头信息,从而使浏览器能正常接收跨域响应。

  • 在控制类上添加注解:

    import org.springframework.web.bind.annotation.CrossOrigin;

    import org.springframework.web.bind.annotation.GetMapping;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RestController;

    @RestController

    @RequestMapping("/api")

    @CrossOrigin(origins = "http://localhost:5173") // 表示 http://localhost:5173 这个路径下的网页可以访问当前控制类

    public class TestController {

    @GetMapping("/data")
    public String getData() {
        return "数据被获取到了";
    }
    

    }

  • 在接口上添加注解:

    import org.springframework.web.bind.annotation.CrossOrigin;

    import org.springframework.web.bind.annotation.GetMapping;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RestController;

    @RestController

    @RequestMapping("/api")

    public class TestController {

    @GetMapping("/data")
    @CrossOrigin(origins = "http://localhost:5173") // 表示 http://localhost:5173 这个路径下的网页可以访问当前方法
    public String getData() {
        return "数据被获取到了";
    }
    

    }

注意:@CrossOrigin 注解可以不写里面的 origins 参数,不写表示可以被所有的路径访问。


2.2 全局配置跨域(适用于整个项目中大量接口都需要跨域的情况)

通过实现 WebMvcConfigurer 接口并重写 addCorsMappings 方法,在 Spring Boot 的配置类中统一设置跨域相关规则,这样就能对项目中所有符合规则的请求都自动处理跨域问题,无需在每个控制器类或者方法上单独添加注解了。

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfig implements WebMvcConfigurer {
	// 一天
    private static final long MAX_AGE = 24 * 60 * 60;

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")   // 对当前路径下的所有请求都应用当前的跨域配置
                .allowedOrigins("*") // 允许的跨域源,可以通过逗号隔开,也可以用 * 表示允许所有源;
                .allowedMethods("*") // 允许的请求方法,可以指定具体的,如:"GET"、"POST"、"PUT"、"DELETE"
                .allowedHeaders("*") // 允许的请求头类型,可以指定具体的,如:"Content-Type", "Authorization
                .maxAge(MAX_AGE);    // 设置请求最大有效时长,在这个时长内,重复的请求就不会发送预检请求
    }
}

2.3 使用过滤器来处理跨域(更底层的实现方式,灵活性高但代码相对复杂一点)

通过自定义一个过滤器 ,在请求进入 Spring Boot 的业务逻辑处理之前拦截请求,并在响应返回给浏览器之前手动设置跨域相关的 HTTP 头信息,以此来实现跨域请求的允许。这种方式能更加灵活地根据业务需求定制跨域处理逻辑,比如可以针对不同的请求路径、请求类型等进行差异化的跨域设置。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {
    // 1天
    private static final long MAX_AGE = 24 * 60 * 60;

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 设置访问源地址,表示所有路劲都可以访问
        corsConfiguration.addAllowedHeader("*"); // 设置访问源请求头,表示所有的请求头都可以
        corsConfiguration.addAllowedMethod("*"); // 设置访问源请求方法,表示所有的请求方法都可以
        corsConfiguration.setMaxAge(MAX_AGE);    // 设置请求最大时长,表示在这个时长内重复的请求不会再次发送预检请求
        source.registerCorsConfiguration("/**", corsConfiguration); // 对当前路径下的所有请求都应用当前的跨域配置
        return new CorsFilter(source);
    }
}

三、结语

这篇文章是通过在后端来解决跨域问题的,而如果想在前端解决的话,我们一般会使用一个代理服务器来解决。首先让前端开发环境下的请求先发送到同域的代理服务器,然后由代理服务器将请求转发到真正的后端接口所在的不同域地址,对于前端来说,它感觉只是在和同域的服务器进行交互,从而绕过了浏览器的同源策略限制,实现跨域请求。

至此,本文结束,如果这篇文章对您有所帮助,希望可以点赞、收藏加关注,感谢。


相关推荐
计算机小白一个1 分钟前
蓝桥杯 Java B 组之岛屿数量、二叉树路径和(区分DFS与回溯)
java·数据结构·算法·蓝桥杯
孤雪心殇3 分钟前
简单易懂,解析Go语言中的Map
开发语言·数据结构·后端·golang·go
White graces14 分钟前
正则表达式效验邮箱格式, 手机号格式, 密码长度
前端·spring boot·spring·正则表达式·java-ee·maven·intellij-idea
菠菠萝宝15 分钟前
【Java八股文】10-数据结构与算法面试篇
java·开发语言·面试·红黑树·跳表·排序·lru
不会Hello World的小苗22 分钟前
Java——链表(LinkedList)
java·开发语言·链表
Allen Bright1 小时前
【Java基础-46.3】Java泛型通配符详解:解锁类型安全的灵活编程
java·开发语言
柃歌1 小时前
【UCB CS 61B SP24】Lecture 7 - Lists 4: Arrays and Lists学习笔记
java·数据结构·笔记·学习·算法
柃歌1 小时前
【UCB CS 61B SP24】Lecture 4 - Lists 2: SLLists学习笔记
java·数据结构·笔记·学习·算法
是姜姜啊!1 小时前
redis的应用,缓存,分布式锁
java·redis·spring
梨落秋溪、2 小时前
输入框元素覆盖冲突
java·服务器·前端