SpringBoot跨域报错全集|CORS、OPTIONS预检、无Access-Control报错全解决

前后端分离架构下,跨域报错是前端联调时最常见的拦路虎,明明接口本地测试正常、后端控制台无异常,前端控制台却疯狂报红,接口请求直接失败、数据无法渲染。这类问题不涉及业务代码,却极易耽误联调进度,新手更是摸不清根源,反复修改配置也无法解决。

✅ 经典CORS报错:No 'Access-Control-Allow-Origin' header is present on the requested resource;

✅ 预检请求失败:OPTIONS请求403/404,正式接口无法调用;

✅ 跨域配置不生效:全局配置、注解配置双双失效;

✅ 自定义请求头跨域失败:token、Authorization等头部无法传递;

✅ 复杂请求跨域失效:POST/PUT/DELETE请求无法正常跨域;

✅ 跨域与拦截器冲突:配置跨域后接口依旧报错。

本篇整理SpringBoot跨域8大高频报错场景 ,从根源讲解跨域原理,每类问题都搭配完整报错原文+核心根因+可直接复制的解决方案,覆盖全局配置、局部配置、避坑优化,不管是简单请求还是复杂请求,照着配置就能彻底解决,建议收藏,联调遇到直接对照!

一、前置科普:什么是跨域?为什么会报错?

浏览器出于安全考虑,遵循同源策略,只有协议、域名、端口三者完全一致,才算同源,不同源之间的请求会被浏览器拦截,这就是跨域。

SpringBoot项目跨域报错,核心原因只有一个:后端未开启CORS跨域支持,未返回对应的跨域响应头,浏览器拦截了请求。后端接口本身正常,只是浏览器的安全限制导致,无需修改业务逻辑,只需配置跨域规则即可解决。

关键区分:简单请求(GET/POST,无自定义请求头)直接触发跨域拦截;复杂请求(PUT/DELETE/自定义头部)会先发起OPTIONS预检请求,预检不通过正式请求直接失败!

二、8大高频跨域报错+完美解决方案

场景1:经典报错 - No 'Access-Control-Allow-Origin' header

1. 前端控制台报错原文

复制代码
Access to XMLHttpRequest at 'http://localhost:8080/api/user/list' from origin 'http://localhost:8081' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

2. 核心原因

最基础的跨域问题,后端完全未配置跨域,响应头中缺少跨域必备的Access-Control-Allow-Origin字段,浏览器直接拦截请求。

3. 解决方案(全局跨域配置,推荐)

新建配置类,实现WebMvcConfigurer接口,全局开启跨域,适配所有接口:

复制代码
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") // 允许请求方式
                .allowCredentials(true) // 允许携带cookie、token等凭证
                .allowedHeaders("*") // 允许所有请求头
                .maxAge(3600); // 预检请求有效期,单位秒
    }
}

场景2:OPTIONS预检请求403/404报错

1. 典型现象

PUT、DELETE、带自定义请求头的接口调用失败,前端控制台显示OPTIONS请求403 Forbidden或404 Not Found。

2. 核心原因

复杂请求会先发起OPTIONS预检请求,后端跨域配置未放行OPTIONS请求,或拦截器、权限框架拦截了预检请求,导致预检失败。

3. 解决方案

  1. 确保跨域配置中包含OPTIONS请求(参考场景1配置);

  2. 拦截器、权限框架(如Security、Sa-Token)放行OPTIONS请求:

    // 拦截器放行OPTIONS请求示例
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    // 放行预检请求
    if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
    return true;
    }
    // 原有拦截逻辑
    return true;
    }

场景3:跨域配置与SpringSecurity冲突,配置失效

1. 典型现象

单独配置跨域正常,集成SpringSecurity后,跨域报错重新出现,配置完全不生效。

2. 核心原因

SpringSecurity过滤器优先级高于跨域配置,请求先被Security拦截,跨域配置未生效,需在Security中开启跨域支持。

3. 解决方案

在Security配置类中开启跨域,整合跨域配置:

复制代码
@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                // 开启跨域,复用自定义CorsConfig
                .cors().and()
                // 关闭csrf防护
                .csrf().disable()
                // 其他权限配置
                .authorizeHttpRequests(auth -> auth.anyRequest().authenticated());
        return http.build();
    }
}

场景4:@CrossOrigin局部注解失效

1. 典型现象

在Controller或接口上添加@CrossOrigin注解,依旧报跨域错误。

2. 核心原因

  • 注解属性配置错误,未放行对应请求;

  • 全局跨域与局部注解冲突;

  • 拦截器、权限框架拦截了请求。

3. 解决方案

规范使用@CrossOrigin注解,适配所有跨域场景:

复制代码
// 控制器类上添加,适配所有接口
@RestController
@RequestMapping("/api/user")
@CrossOrigin(originPatterns = "*", allowCredentials = "true", allowedHeaders = "*", methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE, RequestMethod.OPTIONS})
public class UserController {
    // 接口代码
}

// 单个接口上添加
@GetMapping("/list")
@CrossOrigin
public Result getUserList() {
    return Result.success();
}

场景5:携带token/自定义请求头跨域失败

1. 典型现象

普通接口跨域正常,携带token、Authorization等自定义请求头后,跨域报错重现。

2. 核心原因

跨域配置未放行自定义请求头,浏览器拦截携带自定义头部的请求。

3. 解决方案

修改全局跨域配置,明确允许自定义请求头,或直接放行所有请求头:

复制代码
@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**")
            .allowedOriginPatterns("*")
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
            .allowCredentials(true)
            // 放行所有请求头,包含自定义token
            .allowedHeaders("*")
            .exposedHeaders("Authorization", "token") // 暴露自定义响应头
            .maxAge(3600);
}

场景6:allowCredentials与allowedOrigin冲突报错

1. 前端控制台报错原文

复制代码
Access to XMLHttpRequest at 'http://localhost:8080/api/user/list' from origin 'http://localhost:8081' has been blocked by CORS policy: The value of 'Access-Control-Allow-Origin' cannot be the wildcard '*' when the request's credentials mode is 'include'.

2. 核心原因

开启allowCredentials(true)允许携带凭证后,不能使用allowedOrigins("*")通配符,必须指定具体域名。

3. 解决方案

将allowedOrigins替换为allowedOriginPatterns,即可兼容通配符与凭证携带:

复制代码
// 错误写法
// .allowedOrigins("*")

// 正确写法
.allowedOriginPatterns("*")

场景7:跨域配置后响应头缺失,依旧报错

1. 典型现象

配置了跨域,但响应头中依旧没有Access-Control-Allow-Origin字段,浏览器依旧拦截。

2. 核心原因

  • 跨域配置类未被Spring加载(漏加@Configuration注解);

  • 项目存在多个跨域配置,互相覆盖;

  • 过滤器手动清空了响应头。

3. 解决方案

  1. 检查配置类必须添加@Configuration注解;

  2. 删除多余跨域配置,保留一套全局配置;

  3. 排查过滤器,避免手动清除跨域响应头。

场景8:网关(Gateway)整合后跨域重复报错

1. 典型现象

微服务项目通过Gateway网关调用,配置网关跨域后,依旧报重复跨域头错误。

2. 核心原因

网关和微服务都配置了跨域,导致响应头重复,浏览器识别异常。

3. 解决方案

微服务项目只在网关层配置跨域,删除所有微服务自身的跨域配置,避免重复配置。

三、跨域万能排查步骤

  1. 查看前端报错,定位是Origin缺失、预检失败还是凭证冲突;

  2. 检查全局跨域配置,确保注解、属性配置无误;

  3. 排查拦截器、权限框架,放行OPTIONS预检请求;

  4. 微服务项目只保留网关一层跨域配置;

  5. 查看接口响应头,确认跨域字段是否正常返回。

四、生产环境跨域避坑指南

  • 生产环境禁止使用allowedOriginPatterns("*"),指定具体前端域名,提升安全性;

  • 优先使用全局跨域配置,避免局部注解零散管理;

  • 集成权限框架后,必须同步适配跨域配置,避免过滤器优先级冲突;

  • 复杂请求务必放行OPTIONS预检请求,否则正式请求无法发起;

  • 微服务架构只在网关配置跨域,微服务自身禁止配置跨域;

  • 避免同时使用多种跨域配置方式,防止互相冲突。

五、总结

SpringBoot跨域报错,看似问题繁杂,实则都是配置缺失、配置冲突、权限拦截三大类问题。只要理清跨域原理,统一使用全局跨域配置,适配权限框架与微服务架构,就能彻底解决所有跨域问题。

前后端联调遇到跨域不用慌,对照本文对应场景,复制对应配置,一分钟即可解决,再也不用为跨域问题耽误开发进度。

如果这篇文章帮到你了,记得点赞+收藏🌟!评论区说说你踩过的跨域坑,一起交流避坑~

相关推荐
zs宝来了2 小时前
Spring Boot Starter 机制:如何编写自定义 Starter
spring boot·starter·最佳实践·自定义启动器
weixin_704266052 小时前
Spring 注解驱动开发与 Spring Boot 核心知识点梳理
java·spring boot·spring
无籽西瓜a2 小时前
【西瓜带你学设计模式 | 第五期 - 建造者模式】建造者模式 —— 产品构建实现、优缺点与适用场景及模式区别
java·后端·设计模式·软件工程·建造者模式
小江的记录本3 小时前
【Spring注解】Spring生态常见注解——面试高频考点总结
java·spring boot·后端·spring·面试·架构·mvc
计算机学姐3 小时前
基于SpringBoot的奶茶店点餐系统【协同过滤推荐算法+数据可视化统计】
java·vue.js·spring boot·mysql·信息可视化·tomcat·推荐算法
程序员cxuan3 小时前
来了来了,Claude Code 全架构解析 !!!
人工智能·后端·claude
艾莉丝努力练剑3 小时前
【Linux信号】Linux进程信号(下):可重入函数、Volatile关键字、SIGCHLD信号
linux·运维·服务器·c++·人工智能·后端·学习
常利兵4 小时前
Spring Boot 实现网络限速:让流量“收放自如”
网络·spring boot·后端
掘金者阿豪4 小时前
Claude Code“泄漏源码”曝光:Anthropic 最强终端 AI,原来早就不是聊天工具了
后端