Nginx 302重定向用于升级期间临时跳转,强调临时性、可撤销、不改变客户端感知;需避免对POST用302而改用307,通过变量或文件动态控制开关,精准匹配路径,并透传上下文信息。

在应用升级期间,用 Nginx 的 302 重定向做临时跳转,核心是「不改变客户端感知、不破坏原有链接、可快速启停」。它不是永久迁移(那是 301),而是短期兜底——比如新版本灰度中、数据库迁移时、或旧服务即将下线但部分请求还需兼容处理。
明确 302 的定位:临时性 + 可撤销
302 告诉浏览器“这次去别处,但下次还按原地址来”。搜索引擎不会更新索引,前端 AJAX 请求也能被正确跟随(需 credentials 配置支持),适合升级窗口期(几小时到一两天)。关键点:
- 不要在 location 块里写死 302 到一个长期域名,否则容易遗忘清理
- 避免对 POST 请求直接 302(会变成 GET,丢失数据);如必须跳转,优先改用 307(保留方法和 body)
- 加
Cache-Control: no-store响应头,防止中间代理缓存跳转逻辑
基于变量控制开关:升级时一键启用/关闭
用 Nginx 内置变量或 map 模块动态决定是否跳转,无需 reload 配置。例如:
<!-- 在 http 或 server 块外定义 -->
map $host $should_redirect {
default 0;
~^app\.example\.com 1;
}
# 或更灵活地读取文件(配合外部脚本切换)
map $sent_http_x_maintenance_mode $redirect_flag {
"on" 1;
default 0;
}然后在 server 或 location 中:
location / {
if ($redirect_flag = 1) {
return 302 https://maintenance.example.com$request_uri;
}
proxy_pass http://upstream_app;
}运维只需 echo "on" > /etc/nginx/maintenance.flag,再发 nginx -s reload(或用 openresty 的 shared dict 实现免 reload)。
精准匹配路径,避免误跳
升级通常只影响部分接口(如 /api/v2/),而非全站。用正则 location 精确拦截:
location ~ ^/api/v2/(.*)$ {
# 检查上游是否健康,不健康则跳转兜底服务
proxy_next_upstream error timeout http_500;
proxy_pass http://new_api_backend;
proxy_intercept_errors on;
error_page 502 503 504 = @fallback_v2;
}
<p>location @fallback_v2 {
return 302 <a href="https://www.php.cn/link/b9bfef23813eed0d0d3b92b03805c357">https://www.php.cn/link/b9bfef23813eed0d0d3b92b03805c357</a>;
}这样只有 v2 接口失败时才跳,v1 和静态资源照常走,不影响用户体验。
带上原始请求上下文,方便兜底服务处理
302 跳转时,把关键信息通过 query 参数或 header 透传过去,让目标服务知道“这不是正常访问”:
- 加
X-Upgrading: trueheader(需 proxy_set_header) - 重写跳转 URL:
return 302 https://new.example.com$request_uri?from=legacy&ts=$msec; - 若跳转到同域不同 path,可用 rewrite + break 避免外部暴露(内部重定向)
兜底服务据此可返回友好提示页、降级数据,或记录日志用于监控升级进度。


















