在 Spring Boot 中,跨域(CORS,Cross-Origin Resource Sharing)问题通常发生在前端(如 Vue、React)请求后端 API 时,因 同源策略 限制,导致浏览器拒绝跨域请求。
- 解决跨域的方式
Spring Boot 提供多种方法来解决跨域问题,包括:
- 使用
@CrossOrigin注解(局部配置) - 使用
WebMvcConfigurer进行全局配置 - 使用
CorsFilter进行全局配置 - 使用 Nginx 代理(非 Spring Boot 方案)
方法 1:使用 @CrossOrigin 注解(局部跨域)
如果你只想对某个 Controller 或方法 允许跨域,可以使用 @CrossOrigin 注解。
示例
@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "http://localhost:3000") // 允许 http://localhost:3000 访问
public class MyController {
@GetMapping("/data")
public String getData() {
return "Hello, CORS!";
}
}
📌 说明:
@CrossOrigin(origins = "``http://localhost:3000``")只允许http://localhost:3000访问该控制器的所有方法。- 也可以加在具体的方法上,只允许部分 API 跨域。
限制
- 只能针对特定控制器或方法,不能全局生效。
- 适用于小型项目或单个 API 的跨域需求。
方法 2:全局配置 WebMvcConfigurer
如果你希望全局允许跨域,而不是在每个控制器都加 @CrossOrigin,可以使用 WebMvcConfigurer。
示例
import org.springframework.context.annotation.Bean;
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 {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 允许所有路径
.allowedOrigins("http://localhost:3000") // 允许的来源(可修改为前端地址)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的请求方法
.allowedHeaders("*") // 允许所有请求头
.allowCredentials(true); // 允许携带 Cookie
}
};
}
}
📌 说明:
addMapping("/**"):表示所有路径都允许跨域。allowedOrigins("``http://localhost:3000``"):指定允许访问的前端地址。allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS"):允许的 HTTP 方法。allowedHeaders("*"):允许所有请求头。allowCredentials(true):允许跨域请求携带cookies。
适用场景
- 适用于 大部分 Spring Boot 项目,特别是前后端分离的情况。
- 推荐方式,因为它配置灵活、易维护。
方法 3:使用 CorsFilter 进行全局跨域配置
如果你想完全控制跨域策略,可以使用 CorsFilter 配置。
示例
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;
import java.util.Arrays;
@Configuration
public class CustomCorsFilter {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Arrays.asList("http://localhost:3000")); // 允许的前端地址
config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); // 允许的 HTTP 方法
config.setAllowedHeaders(Arrays.asList("*")); // 允许所有请求头
config.setAllowCredentials(true); // 允许携带 Cookie
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config); // 应用于所有接口
return new CorsFilter(source);
}
}
📌 说明:
CorsFilter方式比WebMvcConfigurer更底层,适用于更复杂的跨域配置需求。- 适用于 Spring Security 开启时,因为
WebMvcConfigurer可能会被Spring Security拦截。
适用场景
- 适用于 Spring Security 开启时,
WebMvcConfigurer可能失效的情况。 - 适用于 更灵活的跨域控制需求。
方法 4:Nginx 代理(非 Spring Boot 方案)
如果你的 Spring Boot 部署在后端,并且前端有独立的服务器(如 Nginx),可以用 Nginx 代理 来处理跨域。
Nginx 配置
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost:8080; # 代理到 Spring Boot
add_header Access-Control-Allow-Origin
; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" ; * add_header Access-Control-Allow-Headers "*
";
add_header Access-Control-Allow-Credentials true;
}
}
📌 说明:
proxy_pass http://localhost:8080;:代理到 Spring Boot 服务器。add_header Access-Control-Allow-Origin *;:允许所有来源访问。add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";:允许的请求方法。add_header Access-Control-Allow-Credentials true;:允许携带 Cookie。
适用场景
- 生产环境推荐,特别是使用 Nginx 作为反向代理时。
- 不会影响 Spring Boot 代码,对性能也更友好。
结论
- 小项目或临时跨域 →
@CrossOrigin - 全局跨域 →
WebMvcConfigurer✅ (推荐) - Spring Security 项目 →
CorsFilter - 生产环境(Nginx 代理) → 让 Nginx 处理跨域