解决前端携带 JWT 请求后端 CORS 报错,核心在于后端正确配置允许Authorization请求头、放行OPTIONS预检方法,并确保 CORS 过滤器在 JWT 认证过滤器之前执行。若前端携带 Cookie,后端Access-Control-Allow-Origin不能配置为*。
先说结论:前端携带 JWT 通常触发非简单请求,后端必须显式响应 OPTIONS 预检请求并放行自定义头部,同时注意过滤器顺序和凭证规则。
- 适合场景:前后端分离架构,前端使用 Axios/Fetch 携带 Token 请求后端接口。
- 先准备:确认后端框架(Spring Boot/Node.js)及是否启用 Spring Security 或自定义鉴权过滤器。
- 再验证:浏览器开发者工具 Network 面板中 OPTIONS 请求状态码为 200/204 且响应头包含允许字段。
命令速用版
以下是 Spring Boot 和 Node.js 两种常见后端的快速配置片段,直接替换或添加至对应配置类。
Spring Boot 全局跨域配置(Java):
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:5173") // 生产环境替换为具体域名
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*") // 允许所有头,包含 Authorization
.allowCredentials(true) // 若前端带 Cookie 需设为 true
.maxAge(3600);
}
}Node.js Express 跨域配置:
const cors = require('cors');
app.use(cors({
origin: 'http://localhost:5173',
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true
}));为什么会这样
浏览器将携带自定义头部(如Authorization)的请求判定为非简单请求,会自动先发 OPTIONS 预检请求。
JWT 通常放在请求头Authorization中,这属于自定义头部。根据 CORS 规范,浏览器在发送实际请求前会先发送 OPTIONS 请求询问服务器是否允许。如果后端没有正确配置允许该头部或未处理 OPTIONS 方法,浏览器会拦截实际请求并报错。此外,若后端有鉴权过滤器(如 JWTFilter),需确保其不会拦截 OPTIONS 预检请求,否则预检失败导致跨域报错。
分步处理
步骤 1:后端放行请求头和方法
在后端 CORS 配置中,allowedHeaders必须包含Authorization,allowedMethods必须包含OPTIONS。Spring Boot 中配置allowedHeaders("*")可覆盖所有头,但需注意生产环境安全。
步骤 2:调整过滤器顺序(Spring Security 场景)
若使用 Spring Security 或自定义 JWT 过滤器,必须将 CORS 过滤器置于鉴权过滤器之前。否则请求先被鉴权拦截,无法到达 CORS 处理逻辑。
操作动作:在配置类中将CorsFilter的优先级设为最高,或使用FilterRegistrationBean设置Ordered.HIGHEST_PRECEDENCE。
步骤 3:前端配置凭证携带
若后端配置了allowCredentials(true),前端 Axios 需设置withCredentials: true。注意:此时后端allowedOrigins不能为*,必须指定具体域名。
步骤 4:处理预检缓存
配置maxAge字段(如 3600 秒),告诉浏览器在一定时间内缓存预检结果,减少 OPTIONS 请求频率。
怎么验证是否生效
打开浏览器开发者工具,进入 Network 面板,刷新页面或触发接口请求。
- 检查点 1:找到目标接口请求,确认其前是否有一个 OPTIONS 请求。
- 检查点 2:OPTIONS 请求状态码应为 200 或 204,而非 401 或 403。
- 检查点 3:点击 OPTIONS 请求,查看 Response Headers,确认包含
Access-Control-Allow-Origin、Access-Control-Allow-Headers(含 Authorization)。 - 检查点 4:实际请求(GET/POST)成功返回数据,控制台无 CORS 红色报错。
常见坑
1. 通配符与凭证冲突
当Access-Control-Allow-Credentials为true时,Access-Control-Allow-Origin不能设置为*,必须指定具体域名,否则浏览器拒绝接收响应。
2. 过滤器顺序错误
在 Spring Boot 中,若 JWT 过滤器排在 CORS 过滤器之前,OPTIONS 请求可能被鉴权逻辑拦截返回 401,导致预检失败。需确保 CORS 过滤器优先级最高。
3. 请求头未完全放行
前端若发送Cache-Control、Pragma等非标准头,后端allowedHeaders也需显式允许,否则预检失败。
常见问题
为什么配置了 CORS 还是报 401 错误?
因为 OPTIONS 预检请求被鉴权过滤器拦截。需在后端配置中放行 OPTIONS 方法不进行鉴权,或调整过滤器顺序让 CORS 先执行。
前端携带 JWT 是否一定触发跨域预检?
是。因为 JWT 通常放在Authorization头中,属于自定义头部,浏览器会强制发起 OPTIONS 预检请求确认服务器是否允许。
生产环境 allowedOrigins 可以写*吗?
若不需要携带 Cookie 凭证,可以写*;若需要携带凭证(withCredentials=true),则必须写具体域名,不能写*。
参考来源
- CSDN 博客:从“跨域报错到彻底解决”:Spring Boot+Security+JWT 实战踩坑指南
- Node.js 解决后端 CORS 跨域问题的终极指南
- CSDN 博客:CORS 跨域问题&解决方法
- springboot 前后端跨域问题 (附上解决方案)
- 博客园:前后端分离 java、jwt 项目进行 CORS 跨域、解决非简单请求跨域问题、兼容性
- 解决 JS 请求跨域时后端 CorsFilter 不生效的问题
- 前后端分别解决跨域问题 CORS 错误
- 解决常见的 CORS 跨域错误情况