Spring Boot 跨域请求未到达后端问题排查记录
一、问题背景
-
前端地址 :
http://168.16.0.169 -
后端地址 :
http://10.0.30.175:82 -
技术栈:Spring Boot(可能包含 Spring MVC / Spring Security)
-
现象描述:
-
已在后端配置全局 CORS:
java@Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowCredentials(true) .maxAge(3600); } -
浏览器访问接口失败
-
主观感觉:请求根本没有到达后端
-
二、排查思路总览
按照「请求链路」自外向内逐层排查:
- 浏览器层(CORS / 预检请求)
- Spring MVC 层(CORS 配置是否生效)
- Spring Security / 拦截器层
- 网络层(跨网段 / 防火墙)
- 接口本身是否被命中
三、关键排查点与结论
1️⃣ 是否真正到达后端(第一性判断)
判断方法:
-
浏览器 DevTools → Network
Status = 0/CORS error→ 请求被浏览器拦截,未到后端4xx / 5xx→ 已到后端
-
后端接口增加日志:
java@GetMapping("/test") public String test() { System.out.println("接口被访问了"); return "ok"; }
结论:
- 未打印日志 → 请求未进入 Spring MVC
2️⃣ CORS 配置本身是否有效
⚠️ 关键坑点:allowCredentials(true) + *
-
浏览器规范要求:
- 带 credentials 的跨域请求
Access-Control-Allow-Origin不能是*
Spring Boot 说明:
allowedOrigins("*")❌allowedOriginPatterns("*")✅(Spring Boot 2.4+)
但:
- 部分浏览器 / 代理环境下仍存在兼容问题
规避方案(推荐):
java
.allowedOriginPatterns("http://168.16.0.169")
.allowCredentials(true)
3️⃣ OPTIONS 预检请求被拦截
触发预检的常见条件
- 非简单请求(PUT / DELETE)
- 自定义 Header(Authorization 等)
withCredentials = true
浏览器行为:
- 先发
OPTIONS - 预检失败 → 真正请求不会发送
Spring Security 常见坑
若项目引入 Spring Security,默认会:
- 拦截 OPTIONS
- 校验 CSRF
解决方案:
java
http
.cors()
.and()
.csrf().disable();
或显式放行:
java
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
4️⃣ 网络层问题(跨网段误区)
已验证事实
ping可达 ❌ ≠ HTTP 可达
常见问题
- 防火墙只放行 ICMP,不放行 82 端口
- 浏览器受代理 / 安全策略限制
验证方式:
bash
curl -v http://10.0.30.175:82/xxx
或使用 Postman 测试
结论判定:
- Postman / curl 正常 → 浏览器问题(CORS / 策略)
- Postman 失败 → 网络或端口问题
四、最终根因总结
该问题不是"接口没写好",而是"请求根本没进入后端"
综合判断,最可能根因是:
- 浏览器跨域请求被拦截(CORS / 预检失败)
- Spring Security 未放行 OPTIONS 请求
allowCredentials(true)与*组合导致浏览器拒绝响应
五、推荐的稳定解决方案(模板)
✅ 通用可落地 CORS 配置(推荐)
java
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("http://168.16.0.169")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}
✅ Spring Security 配合
java
http
.cors()
.and()
.csrf().disable();
六、避坑 Checklist(后续直接对照)
- 浏览器 Network 中是否有 OPTIONS
- OPTIONS 是否返回 200
- 是否使用
allowCredentials(true) - 是否仍使用
*Origin - Spring Security 是否放行 OPTIONS
- Postman / curl 是否能访问接口
- 后端日志是否能看到请求
七、经验结论
"跨域失败 ≠ 后端失败,大多数问题发生在请求抵达之前。"
遇到类似问题,优先判断:
- 是否真正进了 Controller
- 是否被浏览器拦截
- 是否被 Security 拦截
公司内部规范|跨域 / 接口无法访问问题排查规范
适用范围:前后端分离架构、浏览器访问后端 API、Spring Boot / Java 技术栈
目标:统一排查思路,减少无效沟通,快速定位"接口访问失败 / 请求未到达后端"类问题
一、问题定义与典型症状
当出现以下任一情况时,应按本规范排查:
- 浏览器请求接口失败,但后端无任何日志
- 前端报错:CORS error / Network Error / Failed to fetch
- Postman 可访问,浏览器不可访问
- OPTIONS 请求失败,真实请求未发送
- 前端反馈"后端接口没通",但后端确认服务正常
二、统一排查原则(必须遵守)
核心原则
先确认请求是否"真正到达后端",再讨论业务逻辑。
禁止直接:
- 修改业务代码
- 反复调整接口参数
- 盲目重启服务
三、标准排查流程(强制顺序)
Step 1:判断请求是否进入后端(第一性判断)
必做项
-
浏览器 DevTools → Network
Status = 0 / CORS error→ 请求未到达后端4xx / 5xx→ 请求已到达后端
-
后端临时接口日志验证
java
@GetMapping("/health/test")
public String test() {
log.info("health test hit");
return "ok";
}
判定结论
| 现象 | 结论 |
|---|---|
| 无日志 | 浏览器 / 安全 / 网络层问题 |
| 有日志 | 进入后端,转业务排查 |
Step 2:浏览器层(CORS)排查
常见触发跨域的场景
- 前后端不同域 / IP / 端口
- 使用
PUT / DELETE - 自定义 Header(Authorization)
withCredentials = true
必查配置点
-
是否返回以下 Header:
Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-Credentials
强制规范(重点)
-
❌ 禁止:
javaallowedOrigins("*").allowCredentials(true) -
✅ 允许:
javaallowedOriginPatterns("http://frontend-host")
Step 3:OPTIONS 预检请求排查
判断是否存在预检
- Network 中是否出现 OPTIONS
- OPTIONS 是否返回 200
Spring Security 项目强制要求
java
http
.cors()
.and()
.csrf().disable();
或:
java
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll();
⚠️ 若 OPTIONS 被拦截,真实请求不会发送
Step 4:网络层与环境排查
必须明确的事实
ping成功 ≠ HTTP 可访问
标准验证方式
bash
curl -v http://backend-host:port/api
结论判定
| 结果 | 结论 |
|---|---|
| curl 成功,浏览器失败 | 浏览器策略 / CORS |
| curl 失败 | 网络 / 防火墙 / 端口 |
四、统一推荐配置模板(生产可用)
Spring Boot CORS 标准模板
java
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOriginPatterns("http://frontend-host")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}
Spring Security 必配项
java
http.cors().and().csrf().disable();
五、禁止行为(踩坑黑名单)
- ❌ 只看后端代码,不看 Network
- ❌ 未确认是否进入 Controller 就改业务逻辑
- ❌ 使用
*+allowCredentials(true) - ❌ 忽略 OPTIONS 请求
- ❌ 认为"ping 通 = 服务可访问"
六、排查 Checklist(提测 / 联调必过)
- 浏览器 Network 是否有 OPTIONS
- OPTIONS 是否返回 200
- 是否配置 CORS
- 是否使用明确的 Origin
- Spring Security 是否放行 OPTIONS
- curl / Postman 是否可访问
- 后端日志是否可见请求
七、规范性结论(必须统一认知)
跨域 / 接口无法访问问题,80% 发生在请求进入后端之前。
处理顺序必须是:
浏览器 → 安全层 → 网络 → Controller → 业务逻辑
任何跳步排查,均视为不合规。
八、适用收益
- 降低前后端无效沟通成本
- 明确责任边界(浏览器 / 网关 / 后端)
- 提高联调效率
- 减少"玄学改代码"行为