实现多级分类url映射需用nginx的location ^~ /category/配合三级rewrite规则,分别提取cat、subcat、tag参数并保留$args,避免正则干扰与重定向循环。

实现文章分类目录的多级树状结构映射,关键在于把形如 /tech/backend/python 这样的 URL 路径,准确拆解为层级参数(一级:tech,二级:backend,三级:python),并转发给后端统一处理。Nginx 不解析业务逻辑,只做路径识别与参数提取,因此规则必须严格匹配层级、防止越界、保留查询参数。
明确 URL 结构和后端接收方式
先确认你的分类路径规则是否固定层级,比如:
-
/category/tech→ 一级分类 -
/category/tech/backend→ 二级分类 -
/category/tech/backend/python→ 三级分类
后端建议用 query string 接收(调试友好),例如转成:/index.php?cat=tech&subcat=backend&tag=python。
若用 PATH_INFO 或前端控制器(如 Laravel 的 index.php),需确保 Nginx 的 fastcgi_param 配置同步支持。
用 location + rewrite 拆解多级路径
在 server 块中添加带前缀匹配的 location,避免正则干扰性能:
location ^~ /category/ {
rewrite ^/category/([^/]+)/?$ /index.php?cat=$1 last;
rewrite ^/category/([^/]+)/([^/]+)/?$ /index.php?cat=$1&subcat=$2 last;
rewrite ^/category/([^/]+)/([^/]+)/([^/]+)/?$ /index.php?cat=$1&subcat=$2&tag=$3 last;
}
-
^~ /category/确保前缀优先匹配,比正则 location 效率更高 -
([^/]+)限定每段只捕获非斜杠字符,防止/category/a/b/c/d错误命中三级规则 -
last表示重写后重新进入 location 匹配流程,能正确触发 PHP 处理块 - 末尾
/?$允许路径结尾带或不带斜杠,兼容用户输入习惯
保留分页、筛选等查询参数
用户访问 /category/tech/backend?page=2&sort=date 时,原始参数默认会丢失。解决方法有两个:
- 在 rewrite 目标中显式拼接
$args:rewrite ^/category/([^/]+)/([^/]+)/?$ /index.php?cat=$1&subcat=$2&$args last; - 更推荐的方式:用
try_files+fastcgi_split_path_info配合 PATH_INFO,由 PHP 自行解析$_SERVER['PATH_INFO'],天然携带全部原始参数
避免常见陷阱
多级映射容易出错的地方集中在边界和一致性上:
- 不要在正则 location(
~或~*)里用alias,官方不保证行为可靠 - 所有 rewrite 规则按从长到短排列,否则
/category/a/b可能被第一条一级规则提前截断 - 测试时用
curl -I查看响应头,确认状态码是 200 而非 301/302(除非你本意就是重定向) - 上线前检查日志:
error_log /var/log/nginx/error.log notice;,留意 “rewrite or internal redirection cycle” 提示











