0

Nginx return 302 保留查询参数写法:3种正确方式让UTM不再丢失

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

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