apache - .htaccess 重写到子文件夹

标签 apache .htaccess apache2 url-rewriting

目标:

在共享 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,浏览器地址栏显示 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/,这是我不想要的。

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

最佳答案

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

您可以在这里做几件事。

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

    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当尾部斜杠丢失时。

<小时/>

编辑:

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

    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]

关于apache - .htaccess 重写到子文件夹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14051466/

相关文章:

apache - .htaccess:将根 url 重定向到子目录,但保留根 url

regex - 重写除特定模式以外的所有内容的规则

php - Laravel 网站上传 cPanel 错误

node.js - 重写规则但忽略第一个目录部分?

.htaccess - 将 .htaccess 内容移至虚拟主机以提高性能

apache - 无法在 httpd.conf 中禁用目录列表

apache - .htaccess 相同的 url,带或不带/

apache - hive 错误:java.io.IOException:无法创建代理提供程序类org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider

python - 如何使用 apache2 和 mod_wsgi 获取 Django 调试页面

linux - Web 浏览器不显示 htdocs 目录中的 index.html - Apache