问题现象: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辅助作者原创,未经许可,转载请保留原文链接。

发表评论