0

Nginx return 301和rewrite跳转参数保留对比:选对方法让查询字符串不再丢失

2026.05.29 | youres | 4次围观

为什么return和rewrite的参数行为总让人困惑

很多运维在配置Nginx重定向时都踩过这个坑:明明配置了HTTP跳转HTTPS,结果跳转后URL上的查询参数全没了。比如用户访问http://example.com/page?id=123&utm_source=weixin,跳转后变成了https://example.com/page,参数丢失导致流量追踪失效、页面功能异常。

问题的根源在于Nginx的returnrewrite指令在处理查询参数时遵循不同的规则。理解这些规则,才能写出正确的配置。

return 301:参数自动保留,但要注意写法

return 301是Nginx中最简单的重定向方式。它的参数处理规则很直观:

  • 使用$request_uri:自动保留完整的原始URI,包括路径和查询参数
  • 使用$uri:只保留路径,查询参数会丢失

正确的写法

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

这样配置后,http://example.com/page?id=123会跳转到https://example.com/page?id=123,参数完整保留。

错误的写法

return 301 https://$host$uri;  # 参数会丢失!

因为$uri变量只包含路径部分,不包含查询字符串。

rewrite:参数行为取决于问号

rewrite指令的参数处理规则完全不同,核心在于问号(?)的特殊含义。

规则一:不带问号,参数自动追加

如果rewrite的目标URL不带问号,原始查询参数会自动追加到目标URL后面:

rewrite ^/(.*)$ https://example.com/$1 permanent;

访问http://example.com/page?id=123,跳转后变成https://example.com/page?id=123,参数保留。

规则二:带问号,参数被替换

如果目标URL带问号,问号后面的内容会完全替换原始查询参数:

rewrite ^/(.*)$ https://example.com/$1?new=param permanent;

访问http://example.com/page?id=123,跳转后变成https://example.com/page?new=param,原参数丢失。

规则三:问号后为空,参数被清空

如果只想清空查询参数,可以在目标URL后面加一个空的问号:

rewrite ^/(.*)$ https://example.com/$1? permanent;

这样跳转后URL就变成https://example.com/page,没有任何参数。

return和rewrite参数行为对比表

指令写法示例参数行为
return 301return 301 https://$host$request_uri保留全部参数
return 301return 301 https://$host$uri参数丢失
rewriterewrite ^ https://example.com permanent;保留全部参数
rewriterewrite ^ https://example.com?x=1 permanent;替换为新参数
rewriterewrite ^ https://example.com? permanent;清空所有参数

什么时候用return,什么时候用rewrite

推荐使用return的场景

  • 整站HTTP跳HTTPS:最简单最直接的方式
  • 域名整体迁移:如example.comwww.example.com
  • 不需要正则匹配:目标URL固定,逻辑简单

推荐使用rewrite的场景

  • 需要正则捕获URL的一部分:如/old/(.*)/new/$1
  • 需要修改或替换查询参数:如添加、删除、修改特定参数
  • 复杂的URL重写逻辑:需要多层条件判断

实战案例:UTM参数丢失排查与修复

某运营反馈,微信推广链接http://example.com/landing?utm_source=weixin&utm_campaign=spring跳转HTTPS后,GA4后台无法追踪流量来源。

问题配置

server {
    listen 80;
    server_name example.com;
    rewrite ^/(.*)$ https://example.com/$1? redirect;
}

问题在于末尾多了一个?,导致所有查询参数被清空。

修复方案

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

改用return 301配合$request_uri,简洁可靠,参数完整保留。

验证参数是否保留的正确方法

不要用浏览器测试,浏览器会自动跟跳转,不方便观察。用curl的-v参数查看原始响应:

curl -v http://example.com/page?id=123

查看响应头中的Location字段,确认目标URL是否包含查询参数。

总结

Nginx重定向参数处理的核心规则:

  1. return 301$request_uri保留参数,用$uri会丢参数
  2. rewrite不带问号自动追加参数,带问号会替换参数
  3. 整站跳转首选return,URL重写用rewrite
  4. 上线前用curl验证Location头,确保参数正确

掌握这些规则,Nginx重定向配置再也不踩坑。

相关文章

版权声明

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

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