bla*_*328 5 apache .htaccess rewrite apache2
目标:
在共享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}
Run Code Online (Sandbox Code Playgroud)
问题:
这有效,但它会在客户端浏览器中重写URL.
也就是说,用户http://www.example.com/subfolder/home/在他们的地址栏中看到了,但我需要他们才能看到http://www.example.com/home
我的理解是,我所做的事情.htaccess应该导致最终用户看不到的"内部"重写,但看起来我正在进行"外部"重写.
我究竟做错了什么?
[编辑]其他细节:
当用户访问www.example.com,它确实如需要,用户可以看到主页内容从担任了工作public_html/subfolder/default.html,并在浏览器地址栏中说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 (没有尾部斜杠),它会重定向到www.example.com/subfolder/contact/,这是我不想要的.
我觉得应该告诉我什么是错的,但答案仍然没有找到我.
Jon*_*Lin 14
发生这种情况的原因是因为mod_dir.它有一个指令DirectorySlash,它在认为对目录发出请求时重定向浏览器,并且在附加了尾部斜杠的同一URI中缺少尾部斜杠.问题是mod_dir和mod_rewrite应用于URL /文件映射管道中的不同位置.所以mod_rewrite在某一点上破坏了URI,然后当mod_dir做了它的事情时,重写的URI被重定向,因此浏览器的地址栏中的URL改变为包括"隐藏的"内部重写.
你可以在这里做几件事.
您可以在mod_rewrite中自己强制使用尾部斜杠,因此在URI到达mod_dir 之前,浏览器会被重定向以包含尾部斜杠.这意味着您的所有网址喜欢的事情的/home,并/contact包括尾随斜线,如果丢失,你重写代码会重定向和添加.像这样的东西,高于你当前的规则,以便它首先被应用:
RewriteCond %{REQUEST_URI} !^/subfolder
RewriteCond %{DOCUMENT_ROOT}/subfolder%{REQUEST_URI} !-f
RewriteRule ^(.*[^/])$ /$1/ [L,R=301]
Run Code Online (Sandbox Code Playgroud)关闭DirectorySlash所以mod_dir停止执行此重定向.您可以简单地包含DirectorySlash Off在htaccess文件的顶部.但是,这里的缺点是当缺少尾部斜杠时可能存在信息泄露安全问题.
编辑:
要使用索引文件而不使用尾部斜杠,您需要映射到它.尝试将规则更改为:
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]
Run Code Online (Sandbox Code Playgroud)