rewritecond %{request_filename} !-f 和 !-d 用于判断请求路径是否为真实存在的文件或目录,若均不存在则触发伪静态重写;二者仅对紧邻的下一条 rewriterule 生效,且必须使用 %{request_filename}(绝对路径)而非 %{request_uri}。

判断请求的文件或目录是否存在,是 RewriteCond 最常用也最实用的场景之一。核心就是用 -f 和 -d 这两个测试标记,它们不依赖正则,执行快、开销小,且语义清晰。
检查文件是否存在(-f)
用于确认请求路径对应的是一个真实存在的普通文件(比如 .html、.php、.css 等):
-
RewriteCond %{REQUEST_FILENAME} -f:存在即为真 -
RewriteCond %{REQUEST_FILENAME} !-f:不存在才为真(常用于“不是真实文件就走伪静态”逻辑)
注意:%{REQUEST_FILENAME} 是服务器本地绝对路径(如 /var/www/html/about.html),不是 URL 路径,所以它能准确反映磁盘上是否存在该文件。
检查目录是否存在(-d)
用于判断请求路径是否指向一个真实存在的目录:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
-
RewriteCond %{REQUEST_FILENAME} -d:是目录即为真 -
RewriteCond %{REQUEST_FILENAME} !-d:不是目录(或不存在)才为真
典型用途是避免把对真实目录的访问(如 /uploads/)错误地重写到脚本里;也可和 -f 组合使用,实现“既不是文件也不是目录才交由前端控制器处理”。
文件或目录任一存在就跳过重写
这是高性能伪静态配置的标配写法,放在所有 RewriteRule 前面,让静态资源直接放行:
RewriteCond %{REQUEST_FILENAME} -f [OR]RewriteCond %{REQUEST_FILENAME} -dRewriteRule ^ - [L]
含义:如果请求的是真实文件 或者 真实目录,就立即终止规则链([L]),不再执行后续任何 RewriteRule。Apache 不会进入重写引擎处理,响应速度接近原生。
常见组合与避坑点
- 不要写成
RewriteCond %{REQUEST_URI} -f——%{REQUEST_URI}是 URL 路径(如/style.css),不能用于文件系统判断,必须用%{REQUEST_FILENAME} -
-f和-d不支持通配符或正则,只做精确存在性判断,因此非常高效 - 若需判断“文件存在且非空”,可用
-s(size > 0),但极少用到 - 多个条件默认是 AND 关系;要用 OR 必须显式加
[OR]标志,且最后一个条件不能带 [OR]










