1.前言
本文介绍了spring boot中三种解决跨域问题的方式,坚持看完相信对你有帮助。
同时欢迎订阅springboot系列专栏,持续分享spring boot的使用经验。
2.何为跨域
跨域问题是指在 Web 开发中,一个网页的 JavaScript 代码通过 AJAX 请求后端服务器接口时,如果请求的目标地址与当前页面的地址不在同一个域(域名、端口或协议任何一项不同),就会产生跨域问题。这种情况下,根据浏览器的安全机制(同源策略)就会会限制页面的跨域请求,以防止恶意网站对其他网站的访问和操作,保护用户信息安全。
3.跨域问题出现特征
1.没有状态码信息
如果你看到某个请求似乎“失败了”,但并没有具体的HTTP状态码,这可能是因为浏览器出于安全原因阻止了对响应的访问。在开发者工具的网络(Network)面板中,这样的请求可能会被标记为“cancelled”或者没有显示状态码。
2.控制台报错
浏览器通常会在控制台(Console)中打印一条错误消息,说明因为CORS策略,请求被阻止了
4.方式一:使用 @CrossOrigin 注解
这是最直接简单的方式,可以精确控制所有接口
使用方法:在你的控制器类或者控制器方法上添加 @CrossOrigin 注解,可以精确控制某个控制器类、以及下面的某个方法的允许跨域的来源、允许的请求头、允许的请求方法等配置。
示例代码:
@RestController @RequestMapping("/user") @CrossOrigin(origins = "*")//允许所有来源的请求跨域 @Tag(name = "用户模块") public class UserController { private final UserService userService; public UserController(UserService userService) { this.userService = userService; } @PostMapping("/login") @Operation(summary = "用户登录") public UserLoginVO login(@RequestBody @Validated UserLoginDTO userLoginDTO) { return userService.login(userLoginDTO); } }
这种方式解决跨域需要在每个控制器上加注解,属于重复劳动对于不需要精确控制的场景属于重复劳动。可以看下下面方式
5.方式二:自定义 WebMvcConfigurer
通过实现 WebMvcConfigurer 接口来自定义 WebMvc 配置,并覆盖 addCorsMappings 方法以配置全局跨域规则。
示例代码:
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @author mijiupro */ @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 对所有路径生效 .allowedOrigins("*") //允许所有源地址 // .allowedOrigins("https://mijiupro.com","https://mijiu.com ") // 允许的源地址(数组) .allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的请求方法 .allowedHeaders("*"); // 允许的请求头 } }
这种方式实现了全局的配置,但是无法细腻到控制某个方法
6.方式3:使用 Filter 进行跨域配置
创建一个跨域过滤器,在其中设置允许的跨域规则,并将该过滤器添加到 Spring Boot 的过滤器链中。
示例代码:
import jakarta.servlet.*; import jakarta.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import java.io.IOException; /** * @author mijiupro */ @Component public class CorsFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 将 ServletResponse 转换为 HttpServletResponse HttpServletResponse httpResponse = (HttpServletResponse) response; // 设置允许跨域请求的源地址 httpResponse.setHeader("Access-Control-Allow-Origin", "https://mijiupro.com"); // 设置允许的请求方法 httpResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); // 设置允许的请求头 httpResponse.setHeader("Access-Control-Allow-Headers", "*"); // 继续执行 Filter 链 chain.doFilter(request, response); } }
7.最后
这三种spring boot中解决跨域的方式通常第二种跟第一种使用的最多,对于不需要细腻控制到某个接口方法的推荐使用第二种全局配置解决。