mod_rewrite在公用文件夹中不起作用

时间:2013-07-22 17:46:33

标签: .htaccess mod-rewrite

这是我的导演:

root/
├── app/
├── public/
|       ├── css/
|       ├── img/
|       ├── index.php
|       ├── .htaccess
├── .htaccess

我希望将root/文件夹中的每个请求重写到public/文件夹,然后通过index.php变量将网址传递给$_GET
这是我的root/.htaccess

DirectorySlash off
RewriteEngine on
RewriteRule (.*) public/$1

这是我的root/public/.htaccess

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]

没有RewriteCond %{REQUEST_FILENAME} !-d因为我不希望用户看到目录,例如:root/css

当我转到root/app时,它工作正常,我得到$_GET['url'] = 'app'。但是当我去root/public时,我没有得到$_GET['url'] = public;相反,它显示了public文件夹的目录结构。当我转到root/public/(注意尾随斜线)时,我需要root/public/index.php并且它也不会传递变量。
如果你能告诉我如何解决这个问题,我将感激不尽。我希望root/public重写为root/public/index.php?url=public

编辑:当我转到root/public/css时,它会返回$_GET['url'] = 'css'而不是$_GET['url'] = 'public/css'。似乎在访问public文件夹时,它会忽略第一个.htaccess文件。

2 个答案:

答案 0 :(得分:0)

这种情况正在发生,因为您已关闭DirectorySlash。请参阅apache documentation for mod_dir

  

安全警告

     

关闭尾部斜杠重定向可能会导致信息泄露。考虑* mod_autoindex *处于活动状态(Options +Indexes)并且DirectoryIndex设置为有效资源(例如,index.html)的情况,并且没有为该URL定义其他特殊处理程序。在这种情况下,带有斜杠的请求将显示index.html文件。 但是没有尾随斜杠的请求会列出目录内容。

由于“public”是一个目录,当你请求/public它不会通过root的htaccess文件路由到公共时,它会在mod_rewo甚至有机会处理它之前由mod_autoindex提供服务。 / p>

所以你需要将目录斜杠改回 ON (或者只是注释掉那一行,因为它默认是打开的),然后更改公共目录中的规则以删除尾部斜杠,以及处理空白请求(例如/public/):

RewriteEngine on
RewriteRule ^$ index.php?url=public [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*?)/?$ index.php?url=$1 [QSA,L]

编辑:

  

如果我删除DirectorySlash off,当我转到root/css时,它会将我重定向到root/public/css/?url=css。我必须保留它以防止这种情况发生。

然后您需要做的是处理根htaccess文件中的所有内容并在之前路由检查任何实际目录。因此,删除或注释掉公共目录中的RewriteEngine On,并将根目录中的规则更改为:

DirectorySlash Off

RewriteRule ^public/?$ /public/index.php?url=public [L,QSA]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^public/(.*)$ /public/index.php?url=$1 [L,QSA]

RewriteCond %{REQUEST_URI} !^/public/
RewriteRule ^([^/]+)/?$ /public/index.php?url=$1

答案 1 :(得分:0)

当访问public文件夹时,它会跳转到root/public/.htaccess文件,忽略root/.htaccess文件。为了防止这种情况发生,我在.htaccess目录中只使用了一个root文件:

# Prevent redirection to directory: 'root/css' won't turn into 'root/public/css?url=css'
DirectorySlash off

RewriteEngine on

# When 'root/css', 'root/img' or 'root/js' is accessed, return the real path 'root/public/css/...'
RewriteRule ^((css|img|js)/(.+))$ public/$1 [END]
# For all the requests just pass the u
RewriteRule ^(.*)$ public/index.php?url=$1 [QSA,END]