1

我将以 htaccess 和 mod_rewrite 不是我最好的领域这一事实作为开头。我编写了一个供个人使用的 php MVC 框架,在文档根目录中,我有一个名为“public”的文件夹,用于存放 css、js、图像等。每个 HTTP 请求都会针对“public”中的文件进行检查,如果存在,它发送该文件;否则它会重定向到框架的 index.php。

规则有效,但如果在“公共”中进行匹配,它仍会路由到 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]
4

2 回答 2

2

需要加个测试看看请求是否已经指向公共目录,如果没有就触发RewriteRule:

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

请注意,[L]("last") 标志经常被误解。它会阻止在当前 pass中进一步测试和修改请求,但它不能阻止 Apache 从一开始就通过整个规则集运行新修改的请求(这会发生,因为 .htaccess 规则从顶部应用到每个新的或修改后的请求)。因此,您需要添加 RewriteCond 指令以检查您是否正在处理在规则集的前一阶段中指向公用文件夹的请求。

有关“last”标志的更多详细信息,请参阅Apache 2.4 文档。[请注意,Apache 2.4 提供了一个[END]标志,该标志将停止请求进行另一次重写处理,但这个新标志在 Apache 2.2 和更早版本中不可用。]

于 2012-09-08T19:29:58.067 回答
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,...,否则括号并不是真正必要的。

于 2012-09-08T20:04:42.367 回答