Mod_rewrite现有目录到index.php添加查询字符串,但工作正确的不存在


mod_rewrite existing directories to index.php adds query string but works right for non-existing

我的目录结构是这样的:

vhostrootdir/
|- app/
|- public/
   |- css/
   |- img/
   |- js/

这是我的重写:

ServerName vhostname
<Directory  "vhost/root/dir">
    Options FollowSymLinks
    AllowOverride None
    Require local
    RewriteEngine On
    RewriteCond %{CONTEXT_DOCUMENT_ROOT}/public/$1 -f
    RewriteRule ^((?s).*)$ public/$1 [END]
    RewriteRule ^((?s).*)$ index.php?_url=$1 [END]
</Directory>

如果我去vhostname/whatever,然后我的php $_GET["_url"]返回whatever和地址栏保持vhostname/whatever,如所需。

然而,如果我去vhostname/public,那么$_GET["_url"]public/。注意这个额外的'/',尽管这并不困扰我。问题是浏览器地址栏也改变为 vhostname/public/?_url=/public ,这是我绝对不想要的。

为了增加混乱,如果我去vhostname/public/(注意额外的'/'),那么它可以正常工作。我得到$_GET["_url"]public/和地址栏没有改变。

如果我转到vhostname/app,情况也是一样的。

Edit:原来是浏览器历史记录问题。我清除了Chrome的历史记录,这就解决了问题。没关系,这并没有解决它。在将DocumentRoot更改为公共文件夹后,它仍然发生在公共和应用程序url上,但随后清除历史记录,它不再发生在它们上,现在正在公共文件夹子文件夹上发生。

注意,你需要把DocumentRoot指向public/,因为app/不应该通过web访问。

在本例中,设置空路径将导致_url == none,否则_url将包含添加的任何路径。

ServerName vhostname
DocumentRoot /vhost/root/dir/public
<Directory "/vhost/root/dir/public">
    AllowOverride none
    Require local
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteBase /
        RewriteRule ^$ index.php?_url=none [NC,QSA,L]
        # we need to serve static files
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        # pass the path to _url
        RewriteRule ^(.+)$ index.php?_url=$1 [NC,QSA,L]
    </IfModule>

好的,我想我已经找到问题所在了。因为重写之前的URL是解析到一个目录的,而且我省略了末尾的/,所以apache自动发送了一个301 Moved permanent重定向,并添加了末尾的/。我猜由于apache做事情的顺序,重定向也拾取了重写,而不是301重定向从http://<vhostname>/img<vhostname>/img/,它是301重定向到<vhostname>/img/?_url=img

我终于解决了这个问题(我认为),通过添加DirectorySlash off到我的vhost。