Apache mod_rewrite的核心原理是围绕URL-to-filename映射本质,在URL-to-filename和Fixup两个处理阶段介入请求流程:前者执行服务器级规则,后者执行目录级规则;绝大多数为内部重写(地址栏不变),仅加[R]标志才触发外部跳转;规则生效需模块加载、AllowOverride All及RewriteEngine On三者同时满足;Pattern仅匹配路径部分,不含协议域名和查询参数。

Apache mod_rewrite 的核心原理,不是“写对正则就完事”,而是围绕两个关键处理阶段和一次 URL 到文件名的映射本质展开的。它看起来在改 URL,实际是在干预 Apache 内部如何把用户请求的路径,翻译成服务器上真实要执行的文件或处理器。
它运行在 Apache 请求处理的两个钩子上
Apache 处理每个 HTTP 请求是分阶段的,mod_rewrite 主要介入其中两个环节:
- URL-to-filename 阶段:请求刚进来、还没做权限检查时,模块扫描服务器级配置(如 httpd.conf)里的重写规则,尝试把原始 URL 改写成另一个 URL 或直接映射到某个文件路径
- Fixup(修正)阶段:权限验证完成、.htaccess 文件已读取后,模块再执行目录级规则(比如网站根目录下的 .htaccess)。这时物理路径可能已经初步确定,但重写仍可覆盖或调整最终目标
这两个阶段都基于同一个底层机制——把输入的 URI 转换成内部可处理的资源标识。即使你在 .htaccess 里写规则,它也不是“事后补救”,而是在 Apache 已经走到文件系统层面后,仍被允许重新定义“这个请求到底该找谁”。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
它本质上不改变浏览器地址栏,除非你明确要重定向
绝大多数 RewriteRule 是内部重写:用户访问 /article/123,规则把它悄悄转成 /index.php?id=123,浏览器地址栏仍是 /article/123,服务器返回的是 index.php 处理后的结果。只有加上 [R] 或 [R=301] 标志,才会触发外部跳转,让浏览器发起新请求。
- 没加 R:URL 不变,内容是重写后路径产生的
- 加了 R:浏览器地址栏刷新,HTTP 状态码变成 301 或 302
规则生效的前提是三层“放行”都到位
缺一不可,否则规则完全不触发:
-
模块加载成功:用
apache2ctl -M | grep rewrite确认看到rewrite_module (shared) -
目录权限开放:对应目录的
<Directory>块中必须有AllowOverride All(不能是 None 或 FileInfo) -
引擎显式开启:无论是 httpd.conf 还是 .htaccess,第一行得是
RewriteEngine On;虚拟主机里也得单独开
正则匹配的对象是“路径部分”,不含协议和域名
RewriteRule 的 Pattern 只匹配 URL 的 path(例如 /blog/post-1.html),不包含 https://example.com 这部分。查询参数(?key=value)默认不参与匹配,需用 RewriteCond 配合 %{QUERY_STRING} 单独判断。如果想保留原参数,记得加 [QSA] 标志。
- 错误写法:
RewriteRule ^https://site.com/old(.*) /new$1(协议和域名不能写在 Pattern 里) - 正确写法:
RewriteRule ^/old(.*) /new$1 [L,QSA]

















