2011-09-20 69 views
2

我正在使用mod_rewrite对每个与现有文件或目录不匹配的请求进行重写。这是我的配置:如果路径上存在文件,Apache不会重写请求

RewriteEngine On 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule ^.*$ /index.php [NC,L] 

这是用来像/abc/foo/abc/foo/10到我的应用程序URL映射。它工作得很好。

为了提高性能,我的应用程序现在存储调用的结果/abc/foo在文件foo在相应的目录/abc - 这样在第一次调用后改写条件就不再适用(文件不存在)和apache直接提供数据而不必先调用应用程序。工作得很好。

问题是:现在请求/abc/foo/10不再导致URL被重写,而是出现错误“404 File Not Found”。日志条目指出重写条件!-f不再为真,但实际上文件/abc/foo/10确实存在而不是/abc/foo存在,但是一个文件,而不是一个目录。

我该如何得到这个工作?

(多视图被禁用)

+0

让我得到这个正确的,所以当你提出要求'/ ABC /富/ 10',你想要的数据也下/ ABC下FOO被写入到文件夹一个名为10的文件?这是你在第二次电话中所期待的吗? –

+0

不,问题是如果文件'/ abc/foo'存在,调用'/ abc/foo/10'不再匹配'RewriteCond%{REQUEST_FILENAME}!-f'。 – Niko

+0

为什么不先把'RewriteCond%{REQUEST_FILENAME}!-d'放入'RewriteCond%{REQUEST_FILENAME}!-f'中,然后看到结果,并且重写规则^(。*)$而不是^。 * $并直接指向index.php而不是/index.php –

回答

3

您必须在W /对的AcceptPathInfo每DIR/htaccess的上下文。

因此REQUEST_FILENAME匹配存在的部分,与REQUEST_URI不一样。

如果您不关心请求先前在您的rewritecond中映射的位置,请使用REQUEST_URI var。

在per-vh的情况下,这些变量总是相同的。

+0

我对“AcceptPathInfo”不熟悉,是否有助于停用它? – Niko

4

这是因为foo作为文件存在,而apache将foo作为查询字符串传递给附加/ 10。因此,您的应用程序应该向foo文件写入一些额外的代码,该代码还会检查请求是否包含一些额外的url组件,然后处理目录“foo”和文件10的创建。

+0

有没有机会告诉Apache不要这样做? – Niko

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的URL,改变网址:

/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的规则应遵循

+0

谢谢!实际上,我已经对整个缓存系统进行了重构,但仍然对Apache为什么如此表现感到好奇。 – Niko

相关问题