前端携带 JWT 请求后端 CORS 跨域报错怎么配置解决?

文章导读
解决前端携带 JWT 请求后端 CORS 报错,核心在于后端正确配置允许Authorization请求头、放行OPTIONS预检方法,并确保 CORS 过滤器在 JWT 认证过滤器之前执行。若前端携带 Cookie,后端Access-Control-Allow-Origin不能配置为*。
📋 目录
  1. A 命令速用版
  2. B 为什么会这样
  3. C 分步处理
  4. D 怎么验证是否生效
  5. E 常见坑
  6. F 常见问题
  7. G 参考来源
A A

解决前端携带 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必须包含AuthorizationallowedMethods必须包含OPTIONS。Spring Boot 中配置allowedHeaders("*")可覆盖所有头,但需注意生产环境安全。

步骤 2:调整过滤器顺序(Spring Security 场景)

若使用 Spring Security 或自定义 JWT 过滤器,必须将 CORS 过滤器置于鉴权过滤器之前。否则请求先被鉴权拦截,无法到达 CORS 处理逻辑。

操作动作:在配置类中将CorsFilter的优先级设为最高,或使用FilterRegistrationBean设置Ordered.HIGHEST_PRECEDENCE

步骤 3:前端配置凭证携带

若后端配置了allowCredentials(true),前端 Axios 需设置withCredentials: true。注意:此时后端allowedOrigins不能为*,必须指定具体域名。

前端携带 JWT 请求后端 CORS 跨域报错怎么配置解决?

步骤 4:处理预检缓存

配置maxAge字段(如 3600 秒),告诉浏览器在一定时间内缓存预检结果,减少 OPTIONS 请求频率。

怎么验证是否生效

打开浏览器开发者工具,进入 Network 面板,刷新页面或触发接口请求。

  • 检查点 1:找到目标接口请求,确认其前是否有一个 OPTIONS 请求。
  • 检查点 2:OPTIONS 请求状态码应为 200 或 204,而非 401 或 403。
  • 检查点 3:点击 OPTIONS 请求,查看 Response Headers,确认包含Access-Control-Allow-OriginAccess-Control-Allow-Headers(含 Authorization)。
  • 检查点 4:实际请求(GET/POST)成功返回数据,控制台无 CORS 红色报错。

常见坑

1. 通配符与凭证冲突

Access-Control-Allow-Credentialstrue时,Access-Control-Allow-Origin不能设置为*,必须指定具体域名,否则浏览器拒绝接收响应。

2. 过滤器顺序错误

在 Spring Boot 中,若 JWT 过滤器排在 CORS 过滤器之前,OPTIONS 请求可能被鉴权逻辑拦截返回 401,导致预检失败。需确保 CORS 过滤器优先级最高。

3. 请求头未完全放行

前端若发送Cache-ControlPragma等非标准头,后端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 跨域错误情况