Apache RewriteCond 仅作条件判断,不执行跳转;真正实现内部跳转的是无[R]标志的RewriteRule配合[L]等标志,使URL地址栏不变、请求在服务端内部重写到目标路径。

Apache 的 RewriteCond 本身不执行跳转,它只做条件判断;真正实现“内部跳转”(即 URL 不变、服务端内部重写)的是 RewriteRule 配合特定标志(如 [L] 或隐式内部处理),且必须确保没有 [R](重定向)标志。
确认是内部跳转而非外部重定向
关键区别在于是否暴露真实路径给浏览器:
- 有
[R]或[R=301]→ 浏览器地址栏会改变,属于 HTTP 重定向(外部跳转) - 无
[R],仅用[L]、[QSA]等 → 请求在服务器内部被重写到另一路径,URL 地址栏不变
RewriteCond + RewriteRule 实现带条件的内部跳转
例如:当请求的文件不存在时,将请求内部转发到 index.php(常见于 PHP 框架的前端控制器模式):
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L]说明:
-
%{REQUEST_FILENAME}是当前请求映射到的文件系统路径 -
!-f表示“不是真实存在的文件”,!-d表示“不是真实存在的目录” -
^.*$匹配任意路径,index.php是目标脚本,[L]表示这是最后一条规则,停止后续匹配
常见内部跳转场景与写法
以下均为内部重写(非重定向):
-
统一入口(如 WordPress、Laravel):
RewriteRule ^index\.php$ - [L]RewriteCond %{REQUEST_FILENAME} !-fRewriteCond %{REQUEST_FILENAME} !-dRewriteRule . /index.php [L] -
根据 Host 或 User-Agent 做内部路由:
RewriteCond %{HTTP_HOST} ^m\.example\.com$ [NC]RewriteRule ^(.*)$ /mobile/$1 [L] -
隐藏 .php 扩展名(内部映射):
RewriteCond %{REQUEST_FILENAME}.php -fRewriteRule ^(.*)$ $1.php [L]
注意事项
避免踩坑的关键点:
- 规则写在
<Directory>、.htaccess或虚拟主机配置中时,路径匹配基准不同(.htaccess中^匹配的是相对于该文件所在目录的 URI,不含前导斜杠) -
[L]只终止当前轮次的规则链,若启用了FollowSymLinks或多轮重写,可能继续触发;必要时可加[END](Apache 2.3.9+)彻底终止 - 调试时开启
RewriteLog(旧版)或LogLevel alert rewrite:trace3(新版),查看实际匹配过程

















