0

Nginx return 301 保留参数配置方法:3种写法彻底解决查询字符串丢失问题

2026.05.28 | youres | 12次围观

前言

用 Nginx 做 301 重定向时,很多人会遇到这个问题:配置了 return 301 https://example.com/$request_uri,结果跳转后 URL 上的查询参数全丢了。比如 ?utm_source=google&page=2 这种 UTM 参数、广告追踪参数,在重定向后全部消失。

这是 Nginx return 指令的默认行为——不带参数的 return 会丢弃原始的 query string。但这不是无解的,有几种方法可以保留参数,而且每种方法都有它的适用场景。

一、为什么 return 默认不保留参数

先搞清楚原理。Nginx 的 return 指令在处理重定向时,URL 参数的传递规则是这样的:

  • return 301 https://newdomain.com; → 目标 URL 不带任何查询参数
  • return 301 https://newdomain.com/path; → 只跳转固定路径,原参数丢失

这是 Nginx 的设计逻辑——Nginx 认为,如果你写死了跳转目标,就意味着你不想带参数。参数丢失不是 bug,是预期行为。知道了这个,才能理解怎么修复。

二、三种方法保留参数

方法1:$request_uri 自动带参数(最常用)

server { listen 80; server_name oldsite.com; return 301 https://newsite.com/$request_uri; }

原理: $request_uri 变量包含完整的原始 URI,包括查询字符串。例如原始请求是 http://oldsite.com/page?id=5&sort=asc,跳转后变成 https://newsite.com/page?id=5&sort=asc。

适用场景: 整站 HTTP 跳 HTTPS、域名更换且路径保持不变的情况。这是生产环境中最推荐的写法。

注意: 如果目标域名完全换了,路径结构也变了,就不能直接用 $request_uri,否则会把老站的所有参数都带到新站,可能造成问题。

方法2:$is_args + $args 手动拼接(灵活控制)

server { listen 80; server_name oldsite.com; return 301 https://newsite.com/$uri$is_args$args; }

原理拆解:

  • $uri → 只包含路径部分(不含参数)
  • $is_args → 有参数时值为 ?,无参数时为空字符串
  • $args → 查询参数字符串(不含 ?)

三者组合:$uri$is_args$args = 完整路径 + 条件性添加 ? + 参数。相当于:有参数时 /page?id=5,无参数时 /page(? 不出现)。

适用场景: 需要对参数做额外处理时,比如只想保留部分参数而不是全部。

方法3:map 指令过滤参数(高级场景)

map $request_uri $redirect_target { ~/utm_source=  https://newsite.com/$request_uri; ~/fbclid=      https://newsite.com/$request_uri; default        https://newsite.com/$uri$is_args$args; } server { listen 80; server_name oldsite.com; return 301 $redirect_target; }

通过 map 指令可以灵活判断哪些参数要保留、哪些要去掉。比如可以把追踪参数(utm_source、fbclid)清理掉,只保留业务参数。

三、return 和 rewrite 在参数保留上的对比

指令默认行为保留参数方式性能
return 301 URL不带参数(除非 URL 中写明)加 $request_uri 或 $is_args$args快(直接跳转)
rewrite ... redirect自动携带参数(默认行为)默认保留,不想要需用 ? 清空稍慢(需匹配正则)

简单说:return 默认丢参数,rewrite 默认带参数。如果你习惯了 rewrite 的行为,用 return 时一定要记得手动加参数变量。

四、典型踩坑场景

场景1:HTTP 跳 HTTPS 后 GA4 追踪失效

这是最常见的场景。配置:

server { listen 80; server_name _; return 301 https://$host$request_uri; }

$host 保持原有域名,$request_uri 保留完整路径和参数,UTM 参数不会丢失。

场景2:return 在 location 块中参数丢失

location /old { return 301 https://newsite.com/new$is_args$args; }

这个写法会丢失 ? 后面的参数。加上 $is_args$args 即可。

场景3:多级重定向链中参数丢失

如果有多层 return/rewrite,参数可能在某一环丢失。建议保持跳转链尽量简短,并且每级都检查 $request_uri 是否正确传递。

五、验证参数是否保留

配置完不要急着上线,先在本地验证:

curl -I "http://oldsite.com/page?id=5&sort=asc"

看返回头中的 Location,应该是: https://newsite.com/page?id=5&sort=asc。如果 Location 里没有参数,说明配置有问题,回去检查 $request_uri 是否写对了。

六、总结

  • 整站重定向:用 return 301 https://$host$request_uri;,简单可靠
  • 需要控制参数:用 $uri$is_args$args 手动拼接
  • 清理追踪参数:用 map 指令做条件判断
  • 不要忘记参数变量:return 默认不带参数是很多人踩坑的根本原因

核心就一句话:用 return 做重定向,记得手动加上 $request_uri 或 $is_args$args,参数才不会丢。

相关阅读

版权声明

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

发表评论
881文章数 0评论数
作者其它文章