好的,我帮你把原来的博客整理优化一下,把内容改成 最终可用方案,重点突出:
- Spring Boot + Spring Security 统一处理 CORS
- Nginx 只做代理,不重复加 CORS
- Vue3 前端路由 fallback 配置
- 文风简洁,易读
Spring Boot + Spring Security + Vue3 + Nginx 跨域与路由配置实战
在前后端分离项目中,跨域和路由是最常见的两个问题:
- 前端 Vue3 SPA 路由访问
/admin
出现 404 - Spring Boot 后端跨域请求失败,报 CORS 错误
本文总结了实际项目中的最佳实践,并整理出一套完整可用的解决方案。
1️⃣ Spring Boot 跨域配置
Spring Boot 默认不会返回 CORS 头,需要通过实现 WebMvcConfigurer
来统一配置:
package com.dev.blog.admin.config;
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 {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("*") // 允许所有域名
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 支持预检请求
.allowedHeaders("*") // 允许所有请求头
.allowCredentials(false) // 不携带 cookie,如果需要改为 true
.maxAge(3600); // 预检请求缓存时间
}
}
✅ 建议 只在 Spring Boot 处理 CORS,避免 Nginx 重复添加
Access-Control-Allow-Origin
。
2️⃣ Spring Security 配置 OPTIONS 放行
启用 Spring Security 后,需要放行所有 OPTIONS 预检请求,否则浏览器跨域会失败:
package com.dev.blog.admin.config;
import com.dev.blog.jwt.JwtAuthenticationSecurityConfig;
import com.dev.blog.jwt.RestAccessDeniedHandler;
import com.dev.blog.jwt.RestAuthenticationEntryPoint;
import com.dev.blog.jwt.TokenAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configurable
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private RestAuthenticationEntryPoint authEntryPoint;
@Autowired
private RestAccessDeniedHandler deniedHandler;
@Autowired
private JwtAuthenticationSecurityConfig jwtAuthenticationSecurityConfig;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // ⭐ 放行预检
.mvcMatchers("/admin/**").authenticated() // 后端接口需认证
.anyRequest().permitAll() // /login 等接口直接放行
.and()
.exceptionHandling()
.authenticationEntryPoint(authEntryPoint)
.accessDeniedHandler(deniedHandler)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.apply(jwtAuthenticationSecurityConfig)
.and()
.addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
@Bean
public TokenAuthenticationFilter tokenAuthenticationFilter() {
return new TokenAuthenticationFilter();
}
@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
}
✅
/login
可以跨域访问,浏览器预检请求自动通过。
3️⃣ Nginx 配置(只代理,不加 CORS)
Nginx 只负责代理请求,不建议重复加 CORS 头:
server {
listen 80;
server_name api.xxx.com;
location / {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
如果你确实希望 Nginx 返回 CORS 头,也可以在
OPTIONS
请求时直接返回 204,但建议 只在后端处理。
4️⃣ Vue3 前端路由 404 问题
Vue3 使用 history 模式,如果 Nginx 没配置 fallback,访问 /admin
等子路由会 404。
Nginx 配置示例:
server {
listen 80;
server_name xxx.com;
root /www/wwwroot/xxx.com;
index index.html;
location / {
try_files $uri $uri/ /index.html; # SPA 路由 fallback
}
}
5️⃣ 总结
- Spring Boot:统一处理 CORS,允许所有域名和方法
- Spring Security:放行 OPTIONS 请求,避免预检失败
- Nginx:只做代理,避免重复添加 CORS 头
- Vue3:在 Nginx 配置
try_files
,解决 history 路由 404
配置完成后:
/login
可跨域访问/admin/**
接口需要认证- Vue3 SPA 子路由
/admin
不会 404 - 不会再出现 CORS policy 报错