.htaccess重写在匹配后继续进行

时间:2012-09-08 18:49:17

标签: php .htaccess mod-rewrite

我将以htaccess和mod_rewrite不是我最好的区域为前提。我已经编写了一个供个人使用的php MVC框架,在文档根目录中我有一个名为“public”的文件夹,用于css,js,images等。每个HTTP请求都会根据“public”中的文件进行检查,如果存在,它发送该文件;否则它会重定向到框架的index.php。

规则有效,但如果在“public”中进行匹配,它仍会路由到index.php。如果我注释掉重定向到index.php的最后一行,则css和js正确加载。在“公开”比赛结束后,我无法让它停止处理。

提前致谢

Options +FollowSymLinks
RewriteEngine On

#If file exists as public resource
RewriteCond %{DOCUMENT_ROOT}/public/$1 -f
RewriteRule ^(.*) %{DOCUMENT_ROOT}/public/$1 [NC,L]


#Redirect everything else to index.php
RewriteRule ^(.*) index.php [NC,L]

2 个答案:

答案 0 :(得分:2)

您需要添加一个测试,以查看该请求是否已指向公共目录,如果不是,则仅触发RewriteRule:

RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^.*$ index.php

请注意,[L](“last”)标志经常被误解。它会阻止请求在当前传递中进一步测试和修改,但它无法阻止Apache从一开始就通过整个规则集运行新修改的请求(这将因为应用.htaccess规则而发生,从顶部,到每个新的或修改过的请求)。所以你需要添加RewriteCond指令来检查你是否没有处理在规则集的上一次传递中指向公共文件夹的请求。

有关详细信息,请参阅Apache 2.4 documentation for the "last" flag。 [请注意,Apache 2.4提供了[END]标志,该标志将阻止请求再次进行重写处理,但这个新标志在Apache 2.2及更早版本中不可用。]

答案 1 :(得分:1)

看起来好像你正在进行一些不必要的检查,并且每次执行重写时都会触发规则的新传递。

也许尝试这样的事情?

RewriteEngine On

# pass through anything in the domain.com/public directory
RewriteRule ^/public/(.*)$ - [NC,L]

# route everything else to index
RewriteRule ^(.*)$ index.php [NC,L]

这应该在第一遍传递公共目录中的任何内容,其他一切将需要2次传递来解决第二条规则AFAIK。我认为主要的技巧是提供一个不会触发重写的路由,所以你不会触发第二次传递。

请记住,除非您打算将其内容用于重写为1美元,2美元......,否则不一定需要括号。