很多运维朋友在配置 Nginx 重定向时经常会遇到这个问题:用户访问 http://example.com/old-page?id=123,结果被重定向到了 https://example.com/new-page,查询参数 ?id=123 莫名其妙就丢了。这种情况在页面迁移、域名切换、HTTPS 强制跳转等场景下特别常见——参数丢了不说,SEO 权重也跟着打水漂,用户体验更是直接崩掉。
今天这篇就来说清楚:Nginx 重定向时如何保留原始 URL 的查询参数,5 种常见场景 + 完整配置示例,一次搞懂。
一、先搞懂 query string 是怎么回事
在 Nginx 里,URL 分为两部分:一部分是路径(URI),另一部分是查询字符串(query string)。举个例子:
http://example.com/search?q=nginx&page=2
- 路径部分(URI):
/search - 查询字符串(query string):
q=nginx&page=2
Nginx 提供了一系列变量来处理这两部分:
$request_uri— 完整请求 URI,包含路径和查询参数,如/search?q=nginx&page=2$uri— 仅路径部分,不含查询参数,如/search$args— 仅查询参数部分,如q=nginx&page=2$is_args— 如果有查询参数则等于?,没有则为空字符串
记住这四个变量的区别,是理解所有重定向配置的基础。
二、return 指令:需要手动拼接参数
return 指令是最简单的重定向方式,但默认不会自动携带查询参数。看个例子:
server {
listen 80;
server_name example.com;
# 简单重定向,不保留参数
return 301 https://example.com$uri;
}
用户访问 http://example.com/old?id=5,会被重定向到 https://example.com/old,参数 ?id=5 直接丢失。
要在 return 中保留参数,需要手动拼接:
server {
listen 80;
server_name example.com;
# 保留查询参数的写法
return 301 https://example.com$uri$is_args$args;
}
这样 $is_args 会判断是否有参数(有就变成 ?,没有就为空),$args 则是参数本身。访问 http://example.com/old?id=5 就会正确跳转到 https://example.com/old?id=5。
三、rewrite 指令:默认行为与参数控制
1. rewrite 默认保留参数
与 return 不同,rewrite 指令在重定向时默认会携带查询参数。看这个配置:
server {
listen 80;
server_name example.com;
rewrite ^/old-page/(.*)$ /new-page/$1 redirect;
}
用户访问 http://example.com/old-page/product?id=42,会被重定向到 https://example.com/new-page/product?id=42,参数自动保留。
2. 如果不想保留参数,加上 query string 覆盖
rewrite ^/old-page/(.*)$ /new-page/$1? drop redirect;
在重写目标后加一个 ?,就可以丢弃原参数。这里的 ? 是 Nginx rewrite 的特殊语法,用来清空查询参数。
3. rewrite 中自定义参数
rewrite ^/old-page/(.*)$ /new-page/?category=$1&from=old redirect;
这样访问 http://example.com/old-page/tech?id=99,会被重定向到 https://example.com/new-page/?category=tech&from=old&id=99——注意,原始参数仍然追加在后面。如果只想完全替换参数(不追加原始参数),需要用 capture 加问号。
四、5 种常见场景配置
场景1:HTTP 强制跳转到 HTTPS,保留所有参数
server {
listen 80;
server_name www.example.com;
return 301 https://www.example.com$request_uri;
}
server {
listen 443 ssl;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
server_name www.example.com;
# 业务配置
}
用 $request_uri 是最简单的方式,它包含了完整的路径和查询参数。注意:这个配置只对标准端口(80/443)有效。
场景2:单个页面迁移,参数完整传递
server {
listen 80;
server_name www.example.com;
# 旧页面跳转到新页面
location = /old-product {
return 301 https://www.example.com/products$is_args$args;
}
}
用户访问 http://www.example.com/old-product?ref=google&id=789,会跳转到 https://www.example.com/products?ref=google&id=789。
场景3:多路径批量重定向
server {
listen 80;
server_name www.example.com;
# 博客文章迁移 /blog/2018/xxx -> /articles/xxx
rewrite ^/blog/\d{4}/(.*)$ /articles/$1? redirect;
# 标签页迁移
rewrite ^/tag/(.*)$ /topics/$1? redirect;
# 默认 fallback
return 301 https://www.example.com$request_uri;
}
场景4:多域名合并跳转,参数不丢失
server {
listen 80;
server_name old-domain.com www.old-domain.com;
return 301 https://www.new-domain.com$request_uri;
}
所有从旧域名过来的请求,包括带参数的搜索结果页、筛选条件等,都会完整保留到新域名。
场景5:API 版本迁移,查询参数作为路由依据
server {
listen 80;
server_name api.example.com;
# v1 API 跳转到 v2,保留分页和过滤参数
location /api/v1/ {
return 301 https://api.example.com/api/v2$uri$is_args$args;
}
}
用户访问 http://api.example.com/api/v1/users?role=admin&page=3,会跳转到 https://api.example.com/api/v2/users?role=admin&page=3。
五、最容易踩的几个坑
坑1:return 和 rewrite 混用时参数行为不一致
同一套配置里,如果既有 return 又有 rewrite,要注意它们的参数保留逻辑不同。解决方案是统一用一种方式,或者明确在每个 return 里手动拼接参数。
坑2:HTTPS 跳转时用了 $uri 而不是 $request_uri
这是最常见的丢失参数的情况。HTTP 跳 HTTPS 时:
# 错误写法 - 参数丢失
return 301 https://$host$uri;
# 正确写法 - 参数完整
return 301 https://$host$request_uri;
坑3:重定向后参数被重复追加
如果 rewrite 里用了 ? 清空参数,但配置里又有其他 rewrite 导致参数追加两次,就会出现形如 ?id=5&id=5 的重复参数。解决方法是确保每个 rewrite 的目标地址只有一个带 ? 的地方。
坑4:if 条件里访问 $args 的方式不对
在 if 条件判断中想要根据参数值做跳转,需要用正则匹配:
if ($request_uri ~ "^/old-page\?ref=google") {
return 301 https://www.example.com/new-page?source=google;
}
六、调试技巧
如果配置完发现参数还是丢了,或者重定向链不对,可以用以下命令检查配置是否正确:
nginx -t
加载完整配置并查看最终生效的重定向行为:
nginx -T
另外,也可以用 curl 来验证跳转是否正确:
curl -I "http://example.com/old-page?id=123"
看返回的 Location 头里是否包含了完整的查询参数。
总结
Nginx 重定向保留查询参数的核心就三点:
- return 指令:需要手动拼接
$uri$is_args$args才能保留参数 - rewrite 指令:默认保留参数,如果想丢弃或替换需要加
? - HTTP 跳 HTTPS:推荐用
$request_uri自动包含完整 URI
把这两个指令的参数处理逻辑区分清楚,重定向配置就不再是问题。参数保留看似小事,但对 SEO 和用户体验的影响却是实打实的。
相关推荐阅读:
版权声明
本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论