用 rewrite + permanent 在 server 块中配置 301 跳转,正则捕获旧路径 ID 或名称,映射为新版 RESTful URL(如 /categories/5-tech);规则须置于 server 内、避免嵌套 location;辅以兜底和测试确保迁移准确。

直接在对应 server 块中用 rewrite 指令匹配旧分类路径,生成带 slug 的新 URL,并加 permanent 标志实现 301 跳转。关键在于正则捕获分类 ID 或名称,再拼接新版 RESTful 格式。
明确旧目录结构和新路径规则
先理清映射关系。例如旧版博客分类页是 /category.php?id=5 或 /cat/tech,新版统一为 /categories/5-tech 或 /categories/tech。建议列一张表,左边写旧路径正则(如 ^/category\.php\?id=(\d+)$),右边写新路径模板(如 /categories/$1-tech),便于后续配置不漏项。
用 rewrite + permanent 实现 301 跳转
在站点 server 配置里添加规则,优先级高于 location 匹配。常用写法有:
- 跳转带 ID 的旧分类页:
rewrite ^/category\.php\?id=(\d+)$ /categories/$1-permanent; - 跳转旧静态分类路径:
rewrite ^/cat/(\w+)$ /categories/$1 permanent; - 兼容大小写和横线变下划线:
rewrite ^/category/([a-z0-9_-]+)$ /categories/$1 permanent;
注意:所有规则必须放在 server 块内,不能嵌套在 location /old/ 之类块里——否则可能因 location 优先级导致不生效。
兜底处理与避免循环
如果新版路径由后端动态生成 slug(比如 /categories/5-tech 中的 tech 来自数据库),而旧请求无法预知 slug,可先跳到无 slug 版本(如 /categories/5),由后端做 301 二次跳转或内部重写。也可用 try_files 配合 location 做 fallback:
location ^~ /category/ { rewrite ^/category/(.*)$ /categories/$1 permanent; }- 加
if (!-f $request_filename) { rewrite ^/categories/(\d+)$ /categories/$1/ last; }防止因文件不存在触发错误
验证与上线前检查
改完配置后务必测试三类请求:
- 旧 URL 是否返回 301 状态码(用 curl -I 或在线检测工具)
- Location 响应头是否指向正确的新地址,且保留或丢弃了原参数(如
?from=feed是否需要透传) - 搜索引擎爬虫抓取时是否识别为永久迁移(查 GSC 中“旧 URL 索引量下降、新 URL 索引量上升”趋势)
上线后观察 Nginx access 日志,筛选出仍返回 404 的旧分类路径,及时补漏规则。


















