目标:
在共享Apache2.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
提供的主页内容,浏览器地址栏显示的是www.example.com
。
但是,当用户单击主页上的“Contact”链接(编码的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
(没有尾随斜杠),它就会重定向到www.example.com/subfolder/contact/
,这正是我不想要的。
我觉得这应该告诉我出了什么问题,但我仍然没有得到答案。
发布于 2012-12-27 13:10:01
之所以会发生这种情况,是因为mod_dir
。它有一个名为DirectorySlash
的指令,当它认为对一个目录提出了请求,并且后面的斜杠丢失到一个后缀斜杠的URI时,就会重定向浏览器。问题是mod_dir和mod_rewrite在URL/文件映射管道中的不同位置得到应用。因此,mod_rewrite一度破坏了URI,然后当mod_dir完成任务时,重写的URI被重定向,因此浏览器地址栏中的URL更改为包含“隐藏的”内部重写。
你可以在这里做几件事。
/home
和/contact
之类的所有URL都将包含一个尾斜杠,如果缺少一个斜杠,则重写代码将重定向并添加一个。如下所示,超出了当前的规则,以便首先应用该规则:
RewriteCond %{REQUEST_URI}!^/子文件夹RewriteCond %{DOCUMENT_ROOT}/subfolder%{REQUEST_URI} !-f RewriteRule ^(.*^/)$ /$1/ L,R=301DirectorySlash
,以便mod_dir停止重定向。只需将DirectorySlash Off
包含在htaccess文件的顶部即可。然而,这里的缺点是,当后面的斜杠丢失时,a possible information disclosure security issue就会出现。编辑:
为了使用索引文件,没有尾随斜杠,您需要映射到它。尝试将您的规则更改为:
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]
https://stackoverflow.com/questions/14051466
复制