我把前端从 /ais 改到 /kb 后,连续踩了 7 个 Nginx 坑(含 405/413/502/404 终极解法)

张开发
2026/6/25 15:41:19 15 分钟阅读
我把前端从 /ais 改到 /kb 后,连续踩了 7 个 Nginx 坑(含 405/413/502/404 终极解法)
1. 背景看起来只是改个前缀实际上是链路重构项目原来跑在/ais现在要挂到网关:8000/kb/。同时后端有两套服务主后端188.104.159.164:10003预览服务188.104.159.164:8012前端请求统一走/aiskb/...再由 Nginx 分发到不同 upstream。2. 我遇到的典型故障你大概率也会遇到502 Connection refused原因容器里转发到了127.0.0.1:10003但后端不在容器内。405 Not Allowed原因请求没命中 API location掉进了静态location /kb/POST 被静态资源处理逻辑拒绝。413 Request Entity Too Large原因Nginx 默认 body 太小常见 1m。前端登录页404原因后端返回Location: /login但前端实际部署在/kb/login。/kb/license/validate被重写成/license/validate原因rewrite 写猛了把后端真实需要的/kb也干掉了。预览接口走错后端原因/kl/api/saas/element/preview/*应该去8012却被通用规则发到10003。以为是 Host 丢失导致 405结论不是。405 多数是路由命中错误不是 Host 头问题。3. 核心原则非常关键前端前缀、网关前缀、后端真实路径必须逐条列清楚。精确路由必须放在通用路由之前^~ 顺序。只改该改的前缀不要全局无脑 rewrite。登录跳转要做proxy_redirect或兜底重定向兼容。上传场景必须显式设置client_max_body_size。4. 可直接落地的 Nginx 配置我线上用的结构upstream ais_backend { server 188.104.159.164:10003; } upstream ais_preview { server 188.104.159.164:8012; } server { listen 8000; server_name _; root /usr/share/nginx/html; index index.html index.htm; client_max_body_size 2g; location / { return 301 /kb/; } location /kb { return 301 /kb/; } # 预览服务必须放在通用 /aiskb/ 之前 location ^~ /aiskb/kl/api/saas/element/preview/ { rewrite ^/aiskb/(.*)$ /$1 break; proxy_pass http://ais_preview; 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; } # 通用 API location ^~ /aiskb/ { rewrite ^/aiskb/(.*)$ /$1 break; proxy_pass http://ais_backend; proxy_redirect ~^/(login|register|sso|home)(/.*)?$ /kb/$1$2; 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; } # 兼容后端真实需要 /kb 的接口不要 rewrite 掉 /kb location ^~ /kb/license/ { proxy_pass http://ais_backend; proxy_redirect ~^/(login|register|sso|home)(/.*)?$ /kb/$1$2; 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; } # 后端静态兼容 location ^~ /kb/ais/ { rewrite ^/kb/(ais/.*)$ /$1 break; proxy_pass http://ais_backend; 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; } location ^~ /ais/ { proxy_pass http://ais_backend; proxy_redirect ~^/(login|register|sso|home)(/.*)?$ /kb/$1$2; 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; } # 后端返回 /login 时的前端兼容 location ~ ^/(login|register|sso|home)(/.*)?$ { return 302 /kb$uri$is_args$args; } # 前端 SPA location /kb/ { rewrite ^/kb/(.*)$ /$1 break; try_files $uri $uri/ /index.html; } }5. 排错顺序建议收藏先看浏览器 Network状态码 Request URL Method。再看 Nginx access/error确认实际命中的 location 和 upstream。再核对 rewrite 前后 URI 是否符合后端 Controller。大文件上传先排 Nginx413再排后端 multipart 限制。登录跳转问题优先看Location响应头。6. 最后一句这类问题本质不是“会不会写 Nginx”而是你有没有把路径语义设计清楚。只要把“入口路径、网关路径、后端真实路径、重写规则、优先级”画成一张表80% 的线上故障都能提前消失。

更多文章