404、403或错误代理主因是location优先级逻辑混乱:静态资源被正则拦截需用^~ /static/;/api与/api/混用应拆分为= /api重定向和^~ /api/代理;根路径/出错须用= /精确匹配并检查误匹配正则。

动静分离配置中出现 404、403 或请求被错误代理,绝大多数不是语法错误,而是 location 优先级逻辑没理清。关键不在“写了什么”,而在“谁先匹配上、谁被跳过”。下面直击三个最常踩坑的路径匹配场景,讲清楚怎么用优先级逻辑主动控制走向。
静态资源被正则规则意外拦截
典型现象:访问 /static/js/app.js 返回 403,或被 proxy_pass 转发到后端;但 /static/ 目录明明已配置 root。
原因:你写了类似 location ~ \.(js|css|png)$ { ... } 的正则规则,它优先级高于普通前缀匹配(如 location /static/),而 Nginx 在正则匹配阶段就命中了 .js 后缀,根本没走到 /static/ 块。
解法:把静态目录改用 ^~ 修饰,强制终止后续正则检查:
- location ^~ /static/ { root /var/www; }
- 确保这条写在所有 ~ 或 ~* 规则之前(虽顺序不影响 ^~ 与正则的优先级,但放前面更符合阅读习惯)
- 删掉或注释掉针对 /static/ 下文件类型的重复正则规则,避免冗余和冲突
/api 和 /api/ 混用导致后端收不到请求
典型现象:前端调用 /api/users 正常,但直接访问 /api 返回 404;或者后端 Spring Boot 应用期望所有 API 以 /api/ 开头,但 Nginx 把 /api(无尾斜杠)也转发过去了,后端路由不识别。
原因:location /api 匹配 /api、/api/、/apixxx;而 location /api/ 只匹配以 /api/ 开头的路径,不包含 /api 本身。
解法:按语义明确拆分,用精确匹配兜底:
- location = /api { return 301 /api/; } —— 强制补斜杠
- location ^~ /api/ { proxy_pass http://backend; } —— 确保所有 /api/xxx 都走这里,且不被后续正则干扰
- 避免再写 location /api 这种宽泛前缀,除非你真需要覆盖 /apixxx 类路径
根路径 / 被低优先级规则“兜底”出错
典型现象:访问首页 / 返回 400 或空白,但 /index.html 却能正常加载;或者 SPA 应用刷新页面时路由失效。
原因:location / 是最低优先级的普通前缀匹配,一旦上面有 = /、^~ / 或任何正则匹配上 /(比如 location ~ ^/$),它就会被跳过。更常见的是,你写了 location / { try_files $uri $uri/ /index.html; },但前面某条正则规则(如 location ~ \.php$)因匹配逻辑问题意外捕获了 /。
解法:用精确匹配 + 显式 fallback 控制根路径行为:
- location = / { try_files /index.html =404; } —— 专治根路径,不依赖模糊前缀
- location / { try_files $uri $uri/ /index.html; } —— 作为通用 fallback,处理其他路径
- 检查是否有正则规则可能匹配 /(例如 location ~ ^/.*$),这类写法极易误伤,应删除或收紧










