nginx目录结构调整时,301重定向应优先用rewrite+permanent实现路径映射,精准保留查询参数、避免循环和丢参;需正确放置在server或location块中,区分$request_uri与$1用途,并避开if、分号缺失、协议错配、$host依赖等常见错误。

网站目录结构调整时,Nginx 的 301 重定向核心目标是:把旧路径的所有请求,精准、无损地跳转到新路径,同时保留查询参数、不破坏 SEO 权重。关键不是“怎么写”,而是“怎么写才不出错、不循环、不丢参”。
目录结构调整的 301 重定向,优先用 rewrite + permanent
当你要把 /old-category/xxx 改成 /new-section/xxx,或 /blog/2023/... 换成 /articles/2023/... 这类带路径映射的调整,rewrite 是最直接可控的方式,它支持正则捕获和变量替换。
-
permanent标志等价于301,明确告诉搜索引擎这是永久迁移 - 必须放在
server或location块中,且不能嵌套在可能被覆盖的 location 内部(比如别写在location ~ \.php$里) -
$request_uri是完整 URI(含 ? 后参数),而$1是正则捕获内容;两者用途不同,别混用
常见配置示例:
-
将
/posts/年份/文章名→/articles/年份/文章名rewrite ^/posts/(\d{4})/(.*)$ /articles/$1/$2 permanent; -
将整个
/bbs/目录(含子路径)→/forum/rewrite ^/bbs(/.*)?$ /forum$1 permanent;
(
/?兼容/bbs和/bbs/xxx;$1捕获可选的/xxx部分) -
把
/download/file.zip→/assets/files/file.ziplocation = /download/file.zip { return 301 /assets/files/file.zip; }(用
location =精确匹配单文件,比 rewrite 更轻量、更安全)
别踩这些坑
- ❌ 不要用
if ($uri ~ ^/old/)+rewrite组合:if在 location 外使用有已知缺陷,易引发循环或意外匹配 - ❌ 别漏掉分号:
permanent;缺分号会导致 Nginx 启动失败 - ❌ 别在 HTTPS 的
server { listen 443 ssl; }块里写 HTTP 跳转逻辑——端口和协议不匹配,根本不会触发 - ❌ 别依赖
$host做跳转目标:如果用户用 IP 访问或 Host 头异常,$host可能为空,生成https:///new-path这种非法 URL
测试和验证必须做
- 修改后先运行
nginx -t检查语法,再nginx -s reload生效 - 用
curl -I http://yoursite.com/old/path?utm=source查看响应头:必须含HTTP/1.1 301 Moved Permanently和正确的Location: https://yoursite.com/new/path?utm=source - 浏览器测试时清缓存,或用隐身窗口——301 一旦被缓存,改错后很难立刻验证
不复杂但容易忽略











