最常见错误是变量名拼错、大小写不一致或误用上下文变量,如将%{request_uri}写成%{request_uri}或%{request_url},导致条件静默失效;必须严格区分request_uri(url路径字符串)和request_filename(本地文件系统路径),并依配置位置选用正确变量形式。
apache 中 rewritecond 判断条件写错,最常见不是正则写崩,而是变量名拼错、大小写不一致或用了错误上下文变量——比如把 %{request_uri} 误写成 %{request_url} 或 %{request_uri},这类错误 apache 不报语法异常,规则直接静默跳过,导致重写逻辑失效却查不出原因。
变量名必须严格匹配且区分大小写
Apache 的服务器变量(如 REQUEST_URI、REQUEST_FILENAME、HTTPS)是预定义常量,全大写、下划线分隔、不可缩写、不可小写。写成 %{request_uri}、%{REQUESTURI}、%{REQUEST_URL} 都会被视为未定义变量,其值为空字符串,导致条件恒为真或恒为假。
-
RewriteCond %{REQUEST_URI} ^/old/✅ 正确 -
RewriteCond %{request_uri} ^/old/❌ 变量不存在,条件始终不成立 -
RewriteCond %{REQUEST_URL} ^/old/❌ 无此变量,同上 -
RewriteCond %{REQUEST_URI} ^/OLD/❌ 大小写敏感,/old/ 不会匹配
确认你用的是合适变量,别混淆 REQUEST_URI 和 REQUEST_FILENAME
这两个变量用途完全不同,混用是高频失误点:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
-
%{REQUEST_URI}:是浏览器请求的原始路径(如/api/user?id=1),不包含域名、协议,也不转义,纯 URL 字符串;适合做路径前缀判断(如^/admin)或参数过滤(如!^(.*\.(css|js|png))$) -
%{REQUEST_FILENAME}:是 Apache 拼出的本地文件系统绝对路径(如/var/www/html/index.php),仅在 .htaccess 或 Directory 上下文中可靠;用于判断真实文件/目录是否存在(!-f/!-d) - 错误示例:
RewriteCond %{REQUEST_URI} !-f——!-f是文件系统操作符,只能作用于文件路径,不能用于 URL 字符串,这条条件永远为假
用 LogLevel + trace 日志验证变量实际取值
光看配置容易想当然,必须让 Apache 把变量展开给你看:
- 在虚拟主机配置中添加:
LogLevel alert rewrite:trace3 - 加一条测试规则:
RewriteCond %{REQUEST_URI} ^/testRewriteRule ^ - [E=DEBUG_URI:%{REQUEST_URI}] - 访问
/test?x=1后查 error_log,搜索[rewrite:trace3],你会看到类似:[rewrite:trace3] RewriteCond: input='/test?x=1' pattern='^/test' => matched - 如果看到
input=''或input='/'却预期是/test,说明变量名写错,或规则触发上下文不对(比如放在了 Server 级但没配 DocumentRoot)
注意 .htaccess 和主配置中变量行为差异
同一变量在不同配置位置可能表现不同:
- 在
.htaccess中:%{REQUEST_FILENAME}自动基于该文件所在目录拼路径,通常可用 - 在
httpd.conf或VHost中:%{REQUEST_FILENAME}可能为空或不准确,应改用%{DOCUMENT_ROOT}%{REQUEST_URI}或%{DOCUMENT_ROOT}/$1显式构造物理路径 - 例如统一入口规则,在主配置中应写:
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-fRewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d










