2026.05.29 | youres | 8次围观
Nginx return 302 为什么会丢失查询参数
很多人在配置Nginx临时重定向时遇到一个奇怪的问题:用return 302 https://target.com;跳转后,浏览器地址栏里的?utm_source=xxx&utm_medium=xxx全没了。
这不是bug,而是return指令的设计行为:当你在return的目标URL里没有写问号时,Nginx不会自动把原始查询参数拼上去。
对比一下:
rewrite ^(.*)$ https://target.com$1 permanent;—— 会自动把原查询参数附加过去return 302 https://target.com;—— 不会附加任何参数
这就是很多人踩坑的根源。
方法一:用 $is_args $args 手动拼接(推荐)
最标准、最可控的写法:
location /old-page {
return 302 https://www.youres.cn/new-page$is_args$args;
}
$is_args:如果原始请求有查询参数,它的值是?;没有则是空字符串$args:原始请求的查询参数字符串
这样拼接后:
- 原请求
/old-page?utm_source=wechat→ 跳转到/new-page?utm_source=wechat - 原请求
/old-page(无参数)→ 跳转到/new-page(不会多出一个多余的?)
方法二:用 $request_uri 整体带走(最简单)
$request_uri 包含原始路径+查询参数,直接用:
location /old-path {
return 302 https://www.youres.cn/new-path$request_uri;
}
注意:这种方式会把/old-path?utm=xxx整个拼接到目标URL后面,适合新老路径结构一致的场景。如果新旧路径差异大,用方法一更灵活。
方法三:跨域名跳转保留参数
跨域名跳转时同样适用:
location /promo {
return 302 https://partner-site.com/landing$is_args$args;
}
这样用户从 ?ref=wechat 进来的流量,UTM参数会完整传递到合作站点的落地页,方便统一归因。
302 vs 301:参数保留行为完全一样
很多人以为301和302在参数处理上有区别,其实没有。return指令不管是301还是302,参数保留规则完全一样,区别在于浏览器是否缓存这个跳转。
return 301:永久跳转,浏览器会缓存,SEO传递权重return 302:临时跳转,不缓存,适合A/B测试、临时维护页
参数保留的正确写法,两种跳转通用。
常见错误写法
错误一:URL末尾多加了问号
# 错误:会多出一个多余的 ?
return 302 https://target.com/new?;
正确做法是用$is_args动态判断,不要手写?。
错误二:rewrite里用了问号却不知道含义
# 这个问号会清空原有参数!
rewrite ^/old(.*)$ /new$1? permanent;
rewrite替换字符串里的?有特殊含义:问号后面的内容替换原查询参数,如果问号后面是空的,原参数就被清空了。要保留原参数,要么不加问号,要么用$args拼回去。
验证参数是否真的保留了
用curl测试,别只信浏览器地址栏:
curl -L -v "https://www.youres.cn/old-page?utm_source=test" 2>&1 | grep -i location
观察返回的Location头里是否包含了utm_source=test。
相关文章
版权声明
本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论