我正在使用mod_rewrite对每个与现有文件或目录不匹配的请求进行重写。这是我的配置:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [NC,L]
这用于将/abc/foo
或/abc/foo/10
等网址映射到我的应用。它运作得很好。
为了提高性能,我的应用程序现在将/abc/foo
的调用结果存储在相应目录foo
中的文件/abc
中 - 以便在第一次调用后重写条件不再应用(文件不存在),并且apache直接提供数据而无需先调用应用程序。工作正常。
问题是:请求/abc/foo/10
现在不再导致URL被重写,而是收到错误“404 File Not Found”。日志条目表明重写条件!-f
不再为真,但实际上文件/abc/foo/10
不存在。 /abc/foo
存在,但它是一个文件,而不是目录。
我怎样才能让它发挥作用?
(禁用MultiViews)
答案 0 :(得分:4)
这是因为foo作为文件存在,而apache服务foo,其中附加/ 10作为查询字符串传递。因此,您的应用程序应该向foo文件写一些额外的代码,它还检查请求是否包含一些额外的url组件,然后处理目录的创建" foo"和文件10。
答案 1 :(得分:3)
您必须在per / dir / htaccess上下文中使用AcceptPathInfo。
因此REQUEST_FILENAME与现有的部分匹配,与REQUEST_URI不同。
如果您不关心请求先前在重写中的映射位置,请使用REQUEST_URI var。
在per-vh环境中,这些变量总是相同的。
答案 2 :(得分:2)
项目设计有点不对 - 其他人已经指出它不可扩展 - 如果已经有/ abc / foo文件,你怎么能将请求缓存到/ abc / foo / 10?
对此问题的回答以及您的问题是使用子文件夹而不是文件。
而不是缓存结构:
/abc/foo
/abc/bar
...?
使用:
/abc/index.html
/abc/foo/index.html
/abc/bar/index.html
/abc/foo/10/index.html
并且每次使用index.html
创建新目录这次Apache会发现有/ abc / foo文件夹但没有/ abc / foo / 10文件,所以RewriteCond会适用。
修改强>
您也可以尝试不同的方式 - 使用mod_rewrite修改网址,更改网址:
/abc/foo
/abc/bar
/abc/foo/10
类似于:
/cache/abc~foo
/cache/abc~bar
/cache/abc~foo~10
htaccess规则(粗略地):
# redirecting to cache folder and removing last '/'
RewriteCond %{REQUEST_URI} ^/(abc|cde)
RewriteRule ^(.*?)/?$ /cache/$1 [L]
# recursive replacing '/' with '~'
RewriteCond %{REQUEST_URI} ^/cache/.*/
RewriteRule cache/(.*)/(.*)$ /cache/$1~$2 [L]
您的标准htaccess规则应遵循