一、问题背景
项目中引入了一个前端模块warm-flow-ui,其静态资源路径形式如下:
/api/warm-flow-ui/css/index-BxOgKnlB.css现象描述:
- 本地开发环境(IDEA 直接运行 Spring Boot)访问正常,页面及 CSS、JS 均能加载。
- 生产环境(Nginx + Spring Boot)访问同一路径时返回 404:
curl-I http://xxx/api/warm-flow-ui/css/index-BxOgKnlB.css HTTP/1.1404Not Found Server: nginx二、问题分析过程
1️⃣ 本地为什么可以访问?
本地运行时,Spring Boot 直接提供静态资源,无需 Nginx 转发。
Spring Boot 默认会从以下位置加载静态资源:
classpath:/static/classpath:/public/META-INF/resources/
warm-flow-ui的静态文件已经被打包进了 Jar 包中,因此:
访问路径/api/warm-flow-ui/css/index-xxx.css
→ 实际由 Spring Boot 内置的静态资源映射返回。
2️⃣ 生产环境为什么会 404?
生产环境多了一层Nginx 反向代理:
location /api/ { proxy_pass http://127.0.0.1:8188/; }注意这一行配置:proxy_pass的结尾带了 “/”!
这意味着 Nginx 会去掉/api/前缀再转发。
也就是:
请求:/api/warm-flow-ui/css/index-xxx.css
被转发为:/warm-flow-ui/css/index-xxx.css
3️⃣ 验证后端真实路径
直接访问后端服务端口验证:
http://127.0.0.1:8188/warm-flow-ui/css/index-BxOgKnlB.css✅ 能正常访问,说明后端真实暴露路径为/warm-flow-ui/**,
而不是/api/warm-flow-ui/**。
三、问题根因
- 静态文件是存在的,并打包进了 Jar。
- 问题出在Nginx 转发路径与后端实际静态路径不一致。
对应关系如下:
| 项 | 说明 |
|---|---|
| 对外访问路径 | /api/warm-flow-ui/** |
| 后端真实路径 | /warm-flow-ui/** |
因此,需要在 Nginx 层做路径 rewrite 转换。
四、推荐的 Nginx 解决方案
使用rewrite对路径进行明确重写(最清晰也最安全):
location ^~ /api/warm-flow-ui/ { rewrite ^/api/(warm-flow-ui/.*)$ /$1 break; proxy_pass http://127.0.0.1:8188; 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; }配置解释:
rewrite:将/api/warm-flow-ui/**重写为/warm-flow-ui/**。proxy_pass:转发到 Spring Boot 服务。^~:优先匹配,避光被上层/api/规则恶执。
五、经验总结(避坑要点)
- 静态资源如果已打入 Jar,Nginx 仅需代理,不需设置
root或alias。 - 只有静态文件放在窘盘上时,才使用
alias/root。 - ⚠️
proxy_pass结尾是否带/会直接影响路径转发!
很多线上 404 都是因为这个。
六、最终效果
访问路径保持不变:
http://xxx:5666/api/warm-flow-ui/css/index-xxx.cssNginx 转发后端命中路径:
http://xxx:8188/warm-flow-ui/css/index-xxx.css前端页面与静态资源均可正常加载 🎉
七、结语
这是一个“本地正常,生产 404”的经典问题。
本质原因是:运行方式 + Nginx 转发规则 + 静态资源路径不一致。
希望这次排际过程,能帮到遭遇相似问题的同学 🚀