
本文详解如何彻底解决 spring boot(启用 security)与 next.js 前端在开发环境下的 cors 错误,重点推荐使用 next.js 内置的 rewrites 代理机制替代传统 cors 配置,避免预检失败、响应头缺失等常见陷阱。
本文详解如何彻底解决 spring boot(启用 security)与 next.js 前端在开发环境下的 cors 错误,重点推荐使用 next.js 内置的 rewrites 代理机制替代传统 cors 配置,避免预检失败、响应头缺失等常见陷阱。
在开发 Spring Boot + Next.js 全栈应用时,你很可能遇到如下典型错误:
Access to XMLHttpRequest at 'http://localhost:8081/api/v1/auth/login' from origin 'http://localhost:3000/' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource
这个报错看似是后端 CORS 配置失效,但根本原因在于:Next.js 开发服务器(next dev)本身不转发请求,浏览器直接向 http://localhost:8081 发起跨源请求,触发了浏览器的 CORS 检查。而你的 Spring Boot 安全配置中虽已声明 CorsConfigurationSource,却存在两个关键隐患:
-
SecurityFilterChain 中未显式启用 CORS:即使定义了
@Bean CorsConfigurationSource,若未在HttpSecurity中调用.cors(),该配置不会生效; -
WebMvcConfigurer 与 Security 的 CORS 配置冲突:二者同时存在时,Spring Security 的过滤链优先级更高,
WebMvcConfigurer的全局 CORS 映射可能被忽略(尤其当请求匹配到 Security 的authorizeHttpRequests规则时)。
✅ 正确做法:在开发阶段,完全绕过 CORS —— 利用 Next.js 自带的反向代理能力(Rewrites)统一将 /api/... 请求代理至 Spring Boot 后端。这使前后端同源(均为 http://localhost:3000),从根本上消除跨域问题,且无需修改后端任何配置。
✅ 推荐方案:Next.js Rewrites 代理(开发环境首选)
在项目根目录的 next.config.js 中添加重写规则:
// next.config.js
module.exports = {
async rewrites() {
return [
{
source: '/api/:path*',
destination: 'http://localhost:8081/api/:path*' // 注意:destination 路径需与后端实际 API 前缀对齐
}
];
}
};
? 关键细节说明:
dmap-jsapi-skill下载DMap GL地图JSAPI(dmapgl)开发指南。用于编写、审查、调试 DMap 地图 API 代码,涵盖地图初始化、覆盖物渲染、图层管理、事件处理、控件交互等任务。当用户提及 dmap、dmapgl、jsapi‑gl 或相关地图开发需求时自动触发。
source: '/api/:path*'匹配所有以/api/开头的请求(如/api/v1/auth/login);destination: 'http://localhost:8081/api/:path*'将请求代理至 Spring Boot(注意保留/api/前缀,避免后端路由不匹配);- 代理后,前端代码仍调用
/api/v1/auth/login,但实际请求由 Next.js 开发服务器转发,浏览器看到的是同源请求。
⚠️ 若坚持后端处理 CORS(生产/调试场景)
请修正 Spring Boot 配置,确保 Security 主动启用 CORS:
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final JwtAuthenticationFilter jwtAuthFilter;
private final AuthenticationProvider authenticationProvider;
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.cors(cors -> cors.configurationSource(corsConfigurationSource())) // ? 关键:显式启用 CORS
.authorizeHttpRequests(authorize ->
authorize
.requestMatchers("/api/v1/auth/register", "/api/v1/auth/login")
.permitAll()
.anyRequest()
.authenticated()
)
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authenticationProvider(authenticationProvider)
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); // ✅ 必须包含 OPTIONS
configuration.setAllowCredentials(true); // 如需携带 Cookie 或认证头
configuration.addAllowedOrigin("http://localhost:3000");
configuration.applyPermitDefaultValues();
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
❗ 删除
@SpringBootApplication类中的WebMvcConfigurerBean —— 它与 Security 的 CORS 配置冲突,且在 Security 启用后无效。
? 总结与建议
| 场景 | 推荐方案 | 优势 | 注意事项 |
|---|---|---|---|
| 本地开发 | Next.js Rewrites 代理 | 零 CORS 配置、调试直观、规避预检失败、符合现代前端最佳实践 | 确保 destination 路径与后端实际接口一致;仅限 next dev 生效 |
| 测试/生产环境(需真实跨域) | 修正 Spring Security CORS 配置 | 满足真实部署需求 | 务必启用 .cors(...)、允许 OPTIONS 方法、明确设置 allowedOrigins(禁用 * 配合 allowCredentials) |
最终,不要在开发阶段与 CORS “硬刚” —— Rewrites 是 Next.js 官方推荐的、最简洁可靠的解决方案。它让前后端通信回归同源本质,既提升开发体验,又避免因 CORS 配置疏漏导致的隐蔽性故障。











