我在新安装的虚拟 Debian 11 上偶然发现了一个奇怪的行为。在 user/public_html 下,我对一个页面进行了一些更改,但某个时候我的浏览器开始下载索引文件而不是渲染它。
过了好一会儿我才意识到问题出在 index.html.bak 文件上。虽然文件夹中有 index.php,但这个文件还是被下载了。
我已经通过在配置和 .htaccess 中设置 DirectoryIndex 对此进行了测试,并且只要 index.html 在 index.php 之前设置,并且 DirectoryIndex 未设置,我始终可以复制该问题。Index.html.bak 始终在 index.php 之前提供。如果在 DirectoryIndex 中首先设置 index.php,则 index.php 可以正确提供。
奇怪的是,这只发生在 public_html 下,而不是 /var/www 下
我无法在装有旧版 Apache 的旧 Debian 服务器上复制此操作。
这是错误吗?还是我的配置可能有问题?自从这次全新安装以来,我几乎没有动过任何配置。
Apache 版本是
Server version: Apache/2.4.54 (Debian) Server built: 2022-06-09T04:26:43
答案1
Apache 模块mod_mime
请检查您的 Apachemod_mime
设置和Apache 2.4mod_mime
文档。特别是你的MultiviewsMatch
指令设置和相关文件。
请注意以下从中摘录的警告:允许“Any
扩展名匹配,即使mod_mime
无法识别该扩展名”可以引起“不可预测的结果,例如提供网站管理员从未预料到的文件。.old
”.bak
Apache 模块
mod_mime
此模块用于将内容元数据分配给 HTTP 响应所选的内容通过将 URI 或文件名中的模式映射到元数据值。例如,内容文件的文件扩展名通常定义内容的 Internet 媒体类型、语言、字符集和内容编码。此信息在包含该内容的 HTTP 消息中发送,并在选择替代方案时用于内容协商,以便在选择要提供的多个可能内容之一时尊重用户的偏好。请参阅mod_negotiation更多信息内容协商。
具有多个扩展名的文件
文件可以有多个扩展名;扩展名的顺序是通常情况下无关。例如,如果文件欢迎.html.fr映射到内容类型 text/html 和语言法语,然后文件欢迎.fr.html将映射到完全相同的信息。
如果你希望文件名的最后一个点分隔部分只映射到特定的元数据,那么不要使用添加指令。
MultiviewsMatch
指示
// apache.org > 2.4 > mod_mime > multiviewsmatch
MultiviewsMatch
允许三种不同的行为mod_negotiation的多视图功能:Any
NegotiatedOnly
Filters|Handlers
[处理程序|过滤器]
多视图允许对文件进行请求,例如
index.html
,以匹配基本请求后的任何协商扩展,例如index.html.en
,index.html.fr
或index.html.gz
。该
NegotiatedOnly
选项规定,基本名称后面的每个扩展名都必须与mod_mime
内容协商的可识别扩展名相关联,例如 Charset、Content-Type、Language 或 Encoding。这是最严格的实现,具有最少的意外副作用,并且是默认行为。
要包含与
Handlers
and/or相关的扩展Filters
,请将MultiviewsMatch
指令设置为 Handlers、Filters 或两个选项关键字。
您最终可能会允许
Any
扩展程序匹配,即使mod_mime
无法识别该扩展程序。这可能会导致不可预测的结果,例如提供网站管理员从未期望过的文件.old
。.bak
答案2
感谢用户盲点的答案我能够解决这个谜团(至少大部分)并实现合适的配置。
我所有原始问题的答案:
如果DirectoryIndex
index.html 排在 index.php 之前,Apache 将首先优先考虑 index.html,然后再考虑 index.html 的替代版本(例如 index.html.bak),如果 index.php 不存在,则先提供这些版本。
在我的 Apache mods-enabled/userdir.conf 中,Options MultiViews
已默认设置。此选项允许使用MultiviewsMatch
指令来提供替代文件(如 foo.html.fr)。
在我的 Apache 主配置 apache2.conf 中,Options MultiViews
/var/www 选项默认未启用,因此有问题的行为仅发生在用户的 public_html 网站下。
我不知道为什么这两个默认设置不同。
application/x-trash
Debian 默认为 .bak 文件设置了 mime 类型。这就是浏览器下载 .html.bak 文件而不是渲染它们的原因。
我在基于 Debian 的系统上的 Apache 中注意到的内容与 Apache 文档之间存在一些不一致:
apache 文档 mod_mime.html#multiviewsmatch
您最终可能会允许匹配任何扩展名,即使 mod_mime 无法识别该扩展名。这可能会导致不可预测的结果,例如提供网站管理员从未想过会提供的 .old 或 .bak 文件。
事实上,即使MultiviewsMatch NegotiatedOnly
配置了 .old 和 .bak 文件,也会提供这些文件。这些文件扩展名application/x-trash
在 Debian 上的 /etc/mime.types 中分配了 mime 类型。对我来说,这种行为没有多大意义,而且也与文档相矛盾,所以在某种程度上这实际上是一个错误。
现在,如果您不想Multiviews
完全禁用但想要禁用提供某些已知文件类型,您可以在 mods-enabled/mime.conf 中的 apache 中使用例如RemoveType bak
并使用删除它们的 mime 类型MultiviewsMatch NegotiatedOnly
。