.htaccess重写到子文件夹

时间:2012-12-27 08:12:37

标签: apache .htaccess apache2 rewrite

目标:

在共享Apache 2.2框上的虚拟服务器中,我尝试配置.htaccess以无缝地表示public_html文件夹的子文件夹中的文件,就像它们位于根目录中一样。

也就是说,当用户访问http://www.example.com/home时,我需要他或她无缝地(不在客户端浏览器中重写URL)查看来自http://www.example.com/subfolder/home的文件。

我的.htaccess文件如下所示:

RewriteEngine on
RewriteRule !^subfolder/ subfolder%{REQUEST_URI}

问题:

这可行,它会在客户端浏览器中重写URL。

也就是说,用户会在地址栏中看到http://www.example.com/subfolder/home/,但我需要他们才能看到http://www.example.com/home

我的理解是,我在.htaccess中所做的事情应该导致对最终用户不可见的“内部”重写,但看起来我正在进行“外部”重写。

我做错了什么?


[编辑]其他详细信息:

当用户访问www.example.com时, 按需运行,因为用户会看到从public_html/subfolder/default.html投放的主页内容,并且浏览器地址栏显示{ {1}}。

但是,当用户点击该主页上的“联系”链接(编码为www.example.com)时,它会到达,但会在浏览器地址栏中显示href="/contact",就像它已经完成了重定向而不是内部重写。

如果我然后删除地址栏中的www.example.com/subfolder/contact/文字并强制重新加载页面,则可以正常运行 - 它会加载正确的内容,地址栏仍为/subfolder

实施说明:如果有帮助,www.example.com/contact/是包含public_html/subfolder/contact文件的文件夹

另一个观察结果:

如果我打开一个新标签页并输入default.html (请注意尾随斜杠),它会按预期和期望运行。

但是,如果我打开一个新标签并输入www.example.com/contact/ (没有尾随斜杠),它会重定向到www.example.com/contact,这是我不想要的。

我觉得应该告诉我出了什么问题,但答案仍然没有找到我。

1 个答案:

答案 0 :(得分:14)

之所以发生这种情况,是因为mod_dir。它有一个名为DirectorySlash的指令,当它认为对某个目录发出请求时,会重定向浏览器,并且相同的URI缺少尾部斜杠,并附加一个尾部斜杠。问题是mod_dir和mod_rewrite应用于URL /文件映射管道中的不同位置。所以mod_rewrite在某一点上破坏了URI,然后当mod_dir做了它的事情时,重写的URI被重定向,因此浏览器地址栏中的URL改变为包含“隐藏的”内部重写。

你可以在这里做几件事。

  1. 您可以在mod_rewrite中自行强制使用尾部斜杠,这样浏览器就会被重定向,以便在 URI到达mod_dir之前包含尾部斜杠。这意味着您/home/contact之类的所有网址都会包含一个尾部斜杠,如果缺少一个斜杠,您的重写代码将重定向并添加一个。像这样,上面你当前的规则,以便首先应用它:

    RewriteCond %{REQUEST_URI} !^/subfolder
    RewriteCond %{DOCUMENT_ROOT}/subfolder%{REQUEST_URI} !-f
    RewriteRule ^(.*[^/])$ /$1/ [L,R=301]
    
  2. 关闭DirectorySlash,以便mod_dir停止执行此重定向。您只需在htaccess文件的顶部添加DirectorySlash Off即可。但是,当缺少尾部斜杠时,此处的缺点是a possible information disclosure security issue


  3. 编辑:

    为了使用索引文件而不使用尾部斜杠,您需要映射到它。尝试将规则更改为:

        RewriteEngine On
        RewriteCond %{REQUEST_URI} !^/subfolder
        RewriteCond %{DOCUMENT_ROOT}/subfolder%{REQUEST_URI} -d
        RewriteRule ^(.*?)/?$ /subfolder/$1/ [L]
    
        RewriteCond %{REQUEST_URI} !^/subfolder
        RewriteRule ^(.*)$ /subfolder/$1 [L]