nginx栏目合并301重定向核心是精准映射旧栏目url到新路径并保留子路径与参数:统一前缀用location ^~ + return(如/old-category/→/articles/),多栏目归并需多个独立location块,结构变更用rewrite+permanent,务必用$request_uri、强制https、避免if嵌套及规则覆盖。

网站栏目合并时,Nginx 的 301 重定向核心目标是:把旧栏目 URL(如 /old-category/、/blog/、/news/)全部、精准、无损地跳转到新栏目路径(如 /articles/ 或主站根目录),同时保留请求路径中的子路径和查询参数,避免 SEO 权重流失。
关键不是“全站跳转”,而是按栏目粒度做映射——既要覆盖所有旧 URL,又要防止误跳或循环。
栏目路径整体跳转(推荐用 return)
适用于旧栏目有统一前缀,且新位置是固定路径(如 /articles/)。
location ^~ /old-category/ {
return 301 https://example.com/articles$request_uri;
}
-
^~表示前缀匹配,优先级高于正则,性能好、逻辑清晰 -
$request_uri自动携带完整路径+查询参数(如/old-category/tech?id=123→/articles/tech?id=123) - 协议和域名写死为
https://example.com更稳妥(避免$scheme在 HTTP 请求下跳错)
✅ 适用场景:
/blog/xxx→/articles/xxx,/news/→/articles/
多栏目批量合并到同一新路径
多个旧栏目(如 /bbs/、/forum/、/community/)都归并到 /discuss/:
location ^~ /bbs/ { return 301 https://example.com/discuss$request_uri; }
location ^~ /forum/ { return 301 https://example.com/discuss$request_uri; }
location ^~ /community/ { return 301 https://example.com/discuss$request_uri; }
- 每条
location独立生效,互不干扰 - 不要用
if套rewrite,易出错且性能略低 - 若旧路径含多余斜杠(如
/bbs//post),Nginx 默认会规范化,无需额外处理
需要改写路径结构的合并(用 rewrite)
当新栏目不仅换名,还要调整层级或参数(如 /product/123.html → /items/123/):
location ^~ /product/ {
rewrite ^/product/(\d+)\.html$ /items/$1/ permanent;
rewrite ^/product/(.*)$ /items/$1 permanent;
}
- 第一行精确匹配商品 ID 页面,重写为
/items/123/ - 第二行兜底,把其余
/product/xxx全部映射到/items/xxx -
permanent等效于301,但需确保location块内没有其他冲突规则
⚠️ 注意:rewrite 在 location 内使用时,permanent 会触发外部跳转;若想内部重写(地址栏不变),应改用 last + try_files,但这不属于 301 场景。
避免常见坑
-
别漏掉查询参数:始终用
$request_uri(含?a=1&b=2),不用$uri(只含路径) -
HTTPS 强制一致性:如果新站只走 HTTPS,旧请求即使来自 HTTP,也应跳
https://,否则可能被浏览器拦截或降权 -
测试务必清缓存:301 被浏览器强缓存,开发阶段可临时改
return 302验证逻辑,确认无误再切回 301 -
检查是否被其他规则覆盖:确保这些
location块放在server中靠前位置,避免被location /或try_files提前截断
配置完成后,执行:
nginx -t && nginx -s reload curl -I http://example.com/old-category/top10
看到 HTTP/1.1 301 Moved Permanently 和正确的 Location 头,即成功。











