0

Nginx return 302 不保留参数解决方法:3种正确配置让查询字符串不再丢失

2026.05.30 | youres | 2次围观

问题现象:return 302 后参数莫名其妙消失了

很多人在 Nginx 里配了 return 302 https://example.com$request_uri;,以为这样能把所有请求(包括查询参数)一并转过去。但实际测试会发现:原始请求的 ?utm_source=xxx&utm_medium=xxx 在重定向后完全丢失,Google Analytics 里看不到任何来源数据。

这不是 Nginx 的 bug,而是 return 指令的默认行为:当你在重定向目标 URL 里没有显式写出查询参数时,Nginx 不会自动把原请求的查询字符串附加过去。

原因分析:return 和 rewrite 在参数处理上的核心差异

要搞清楚为什么参数会丢,得先明白 Nginx 两个重定向指令的本质区别:

  • rewrite:默认会把原请求的查询参数(除你用 ? 显式覆盖的情况外)自动附加到新 URL 后面。
  • return:不会对 URL 做任何自动的参数拼接,你写什么就是什么。

所以 return 302 https://example.com$request_uri; 虽然用了 $request_uri,但如果你用的是不含查询参数的写法,参数就会丢。

方法一:用 $request_uri 保留完整原始请求(推荐)

$request_uri 是 Nginx 内置变量,它的值是包含查询字符串的完整原始请求 URI。用它来拼接重定向目标 URL,参数不会丢:

server {
    listen 80;
    server_name example.com;
    return 302 https://www.example.com$request_uri;
}

注意$request_uri 已经包含了最前面的 /,所以目标 URL 里不要多写一个 /,否则会出现双斜杠。

正确:https://www.example.com$request_uri
错误:https://www.example.com/$request_uri(会变成 https://www.example.com//path?x=1

方法二:用 $is_args 和 $args 按需拼接参数

如果你需要在重定向时添加新参数,或者想精确控制哪些参数被传递,可以用 $is_args$args 组合:

server {
    listen 80;
    server_name example.com;
    return 302 https://www.example.com/new-path$is_args$args;
}
  • $is_args:如果原请求有查询参数,它的值是 ?;如果没有,是空字符串。
  • $args:原请求的查询参数字符串(不含 ?)。

这样拼接的效果是:有参数就自动加 ?,没参数就不加,不会出现多余的 ? 或双 ? 问题。

方法三:302 场景下用 307/308 保留 POST 请求体

上面的方法解决了查询参数的保留问题,但还有一个隐藏陷阱:302 重定向会导致 POST 请求变成 GET,请求体(POST body)会丢失。

如果你的场景里有表单提交或 API 调用,需要用 307 或 308 来代替 302:

server {
    listen 80;
    server_name example.com;
    return 307 https://www.example.com$request_uri;
}
  • 307:临时重定向,保留请求方法和请求体(POST 仍然是 POST)。
  • 308:永久重定向,同样保留请求方法和请求体。
  • 302:大多数浏览器会把 POST 静默转成 GET,请求体丢失。

完整配置示例:HTTP 跳转 HTTPS 并保留 UTM 参数

这是最常见的实战场景,把 HTTP 请求重定向到 HTTPS,同时完整保留 UTM 等查询参数:

server {
    listen 80;
    server_name example.com www.example.com;
    # 方法一:用 $request_uri(最简洁)
    return 302 https://www.example.com$request_uri;
}

# 如需保留 POST 请求体,改用 307:
server {
    listen 80;
    server_name example.com www.example.com;
    return 307 https://www.example.com$request_uri;
}

排查技巧:用 curl 验证参数是否真的保留了

配完之后,用 curl 验证一下重定向是否按预期工作:

# -L 跟随重定向,-v 显示详细信息
curl -L -v "http://example.com/path?utm_source=test&utm_medium=email"

# 只看最终重定向目标
curl -I "http://example.com/path?utm_source=test&utm_medium=email"

检查响应头里的 Location 字段,确认查询参数完整出现在目标 URL 里。

相关文章

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论