Apache RewriteCond %{REQUEST_FILENAME}!-f 文件存在时失效问题排查
问题根因
你遇到的判定异常是两个机制共同导致的:
- 你已经查到的
%{REQUEST_FILENAME}变量默认绑定的是用户初始请求的路径,不会随重写规则的执行自动更新,因此第二块规则判断的始终是最原始的/app/xxx路径是否存在,而非第一块重写后的/some-site/map-app/xxx路径 - 第一块重写规则未加
[L]标记,重写后规则会继续向下执行,没有触发Apache的重写规则回溯流程,REQUEST_URI等变量也不会同步更新为重写后的结果
修复方案
调整后的配置如下:
<IfModule mod_rewrite.c> RewriteEngine On # 所有/app开头的请求先映射到目标目录,不需要提前判断原始路径是否存在 RewriteRule ^app/?(.*)$ /some-site/map-app/$1 [NC,L,QSA] # 对映射后的目录做兜底判断,用重写后的当前路径判定文件是否存在 RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d RewriteRule ^some-site/map-app/?(.*)$ /some-site/map-app/index.html [NC,L,QSA] </IfModule>
逻辑说明
- 第一块规则移除了不必要的初始路径存在性判断,增加
[L]标记完成路径映射后终止当前轮规则遍历,触发Apache自动回溯,此时REQUEST_URI会更新为第一块重写后的路径 - 第二块规则改用
%{DOCUMENT_ROOT}%{REQUEST_URI}拼接得到当前重写后路径对应的服务器真实文件路径,以此判断文件/目录是否存在,仅当不存在时才执行SPA兜底重写
效果验证
你给出的期望请求都会正常匹配:
/app/-> 重写为/some-site/map-app/,无对应文件则兜底到/some-site/map-app/index.html/app/map/id-3-> 重写为/some-site/map-app/map/id-3,无对应文件则兜底到/some-site/map-app/index.html/app/app.js-> 重写为/some-site/map-app/app.js,文件真实存在,不触发兜底,直接返回静态文件/app/assets/img/1.png-> 可配合你未贴出的对应重写逻辑正常匹配
内容的提问来源于stack exchange,提问作者Seph Reed
相关产品推荐
相关产品推荐

