用 %{REQUEST_FILENAME} 配合 -f 或 -d 可准确判断请求路径是否对应真实文件或目录,因其代表服务器本地绝对路径;常用组合为“-f [OR] -d”加“^ - [L]”守卫静态资源,避免误重写。

直接用 RewriteCond %{REQUEST_FILENAME} 配合 -f(文件)或 -d(目录)标志,就能准确判断请求路径是否对应磁盘上真实存在的资源。关键在于必须用 %{REQUEST_FILENAME},而不是 %{REQUEST_URI} 或其他字符串变量——只有它代表服务器本地绝对路径,才能被 Apache 正确解析为文件系统对象。
检测真实文件是否存在
用 !-f 表示“不是真实文件”,常用于 SPA 或 PHP 路由场景,避免把对 /js/app.js 这类静态资源的请求也转发给入口脚本:
RewriteCond %{REQUEST_FILENAME} !-f
这条条件成立时,说明请求的路径在磁盘上没有对应的真实文件,后续规则才可能执行。单独使用意义不大,一般和目录判断组合。
检测真实目录是否存在
用 -d 判断是否为真实目录,比如放行 /uploads/ 这类有实际内容的目录,不让重写干扰其默认行为:
RewriteCond %{REQUEST_FILENAME} -d
注意:%{REQUEST_FILENAME} 是 Apache 自动拼出来的完整路径(如 /var/www/html/uploads),不是 URL 字符串。所以它能真正调用系统 stat() 检查目录是否存在。
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
合并判断:文件或目录任一存在就跳过重写
最常用、最稳妥的前置守卫写法,确保静态资源不被误伤:
RewriteCond %{REQUEST_FILENAME} -f [OR]RewriteCond %{REQUEST_FILENAME} -dRewriteRule ^ - [L]
这里 [OR] 只加在第一行末尾,第二行不加;^ - [L] 表示“匹配任意路径,但什么也不改,立即终止重写流程”。这样,只要请求的是真实文件或真实目录,后面所有规则都不再执行。
常见错误与避坑点
以下写法都不可靠:
-
RewriteCond %{REQUEST_URI} -d——%{REQUEST_URI}是纯字符串(如/admin/),不能配合-d使用,会报错或恒为假 -
RewriteCond %{REQUEST_FILENAME} !-s——-s要求文件存在且非空,但目录没有大小概念,对目录永远不匹配 - 多个
RewriteCond没加[OR]却想表达“或”逻辑 —— 默认是“且”,全部为真才算满足
本质上,-f 和 -d 是文件系统级判断,不是字符串匹配。它们只认物理路径变量,且依赖 Apache 有足够权限读取目标目录。

















