apache mod_rewrite路径映射核心是用rewriterule将请求url映射到实际文件或路径,关键在于匹配模式(仅路径部分)、捕获变量($1等)、重写目标及flag(如l[qsa])的协同作用,并需区分.htaccess与虚拟主机配置中路径匹配的差异。

Apache 的 mod_rewrite 路径映射核心是用 RewriteRule 把请求 URL 映射到实际文件或路径,关键在于理解匹配模式、捕获变量和重写目标之间的关系,同时注意上下文(.htaccess 还是虚拟主机配置)和 flag 的作用。
基础语法与路径匹配逻辑
RewriteRule 模式 替换 [flag] 是基本结构。模式是正则表达式,匹配的是**URL 路径部分(不包含协议、域名、查询字符串)**。例如访问 /blog/post-123.html,匹配的是 ^/blog/post-(\d+)\.html$ 中的 /blog/post-123.html。
- 在
.htaccess中,匹配时自动去掉当前目录前缀(如网站根目录下 .htaccess,^post-(\d+)\.html$就能匹配/post-123.html) - 在虚拟主机或主配置中,匹配的是完整路径(含开头的
/),所以通常要写^/post-(\d+)\.html$ - 捕获组用
(...),可在替换中用$1、$2引用;服务器变量用%{...},如%{REQUEST_URI}
常见路径映射写法示例
以下写法假设启用 RewriteEngine On,且放在合适上下文中:
Apache 2.4.62 官方 tar.gz 源码包是 Linux 及类 Unix 系统构建 Web 服务器的核心基础。通过源码编译安装,开发者能够灵活定制模块、优化性能并精准控制安装路径,满足多样化的业务需求。
-
伪静态 → 真实 PHP 文件:
RewriteRule ^article/(\d+)$ /article.php?id=$1 [L]→ 访问/article/123实际执行/article.php?id=123 -
隐藏 .php 后缀:
RewriteCond %{REQUEST_FILENAME}.php -fRewriteRule ^(.+)$ $1.php [L](先判断文件存在再重写) -
强制带 www 或去 www:
RewriteCond %{HTTP_HOST} ^example\.com$RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L] -
目录别名映射:
RewriteRule ^api/(.*)$ /var/www/backend/$1 [L](需配合RewriteOptions InheritBefore或使用[P]代理)
必须注意的 flag 和细节
flag 决定规则行为,几个关键 flag 常一起用:
-
[L]:最后一个规则,匹配后停止后续规则处理(不加可能被后续规则覆盖) -
[QSA]:保留原查询字符串,比如/old?x=1→/new?y=2加上[QSA]变成/new?y=2&x=1 -
[R]或[R=301]:触发 HTTP 重定向(浏览器地址栏会变),不加才是内部重写(URL 不变) -
[NC]:忽略大小写;[PT]:让重写结果继续被其他模块处理(如 alias)
特别注意:如果重写目标是文件系统路径(非 URL),要用 [E=... 或 Alias 配合,一般推荐用 URL 形式重写,由 Apache 自动映射到文件。
调试技巧和常见坑
路径映射出错时,优先检查日志和规则顺序:
- 开启重写日志(仅开发环境):
RewriteLogLevel 3+RewriteLog "/path/to/rewrite.log"(Apache 2.4+ 改用LogLevel alert rewrite:trace3) - 规则顺序很重要:靠前的
[L]会截断,测试时可临时去掉[L]看是否被后续规则干扰 - 避免循环重写:比如
RewriteRule ^(.*)$ /index.php没条件限制,会导致无限循环,应加RewriteCond %{REQUEST_FILENAME} !-f和!-d -
.htaccess中的重写路径相对于该文件所在目录,不是网站根目录,容易误判相对路径










