铬
Chrome (编写时为 38 版) 有 3 种方法来确定 MIME 类型,并按特定顺序进行。下面的sn-p来自文件src/net/base/mime_util.cc,方法MimeUtil::GetMimeTypeFromExtensionHelper。
// We implement the same algorithm as Mozilla for mapping a file extension to
// a mime type. That is, we first check a hard-coded list (that cannot be
// overridden), and then if not found there, we defer to the system registry.
// Finally, we scan a secondary hard-coded list to catch types that we can
// deduce but that we also want to allow the OS to override.
硬编码列表出现在文件的前面一点:https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=170(kPrimaryMappings 和 kSecondaryMappings)。
例如:当从安装了 Microsoft Excel 的 Windows 系统上传 CSV 文件时,Chrome 会将此报告为application/vnd.ms-excel。这是因为.csv没有在第一个硬编码列表中指定,所以浏览器回退到系统注册表。 HKEY_CLASSES_ROOT\.csv 有一个名为 Content Type 的值,该值设置为 application/vnd.ms-excel。
Internet Explorer
再次使用相同的示例,浏览器将报告application/vnd.ms-excel。我认为假设 Internet Explorer (撰写时为第 11 版) 使用注册表是合理的。可能它还使用了 Chrome 和 Firefox 等硬编码列表,但它的封闭源特性使其难以验证。
火狐
如 Chrome 代码所示,Firefox (编写时为 32 版) 以类似的方式工作。来自文件uriloader\exthandler\nsExternalHelperAppService.cpp、方法nsExternalHelperAppService::GetTypeFromExtension的片段
// OK. We want to try the following sources of mimetype information, in this order:
// 1. defaultMimeEntries array
// 2. User-set preferences (managed by the handler service)
// 3. OS-provided information
// 4. our "extras" array
// 5. Information from plugins
// 6. The "ext-to-type-mapping" category
硬编码列表出现在文件的前面,靠近第 441 行。您正在寻找defaultMimeEntries 和extraMimeEntries。
使用我当前的配置文件,浏览器将报告 text/csv,因为在 mimeTypes.rdf 中有一个条目(上面列表中的第 2 项)。对于没有此条目的新配置文件,浏览器将报告 application/vnd.ms-excel(列表中的第 3 项)。
总结
浏览器中的硬编码列表非常有限。通常,浏览器发送的 MIME 类型将是操作系统报告的类型。正如问题中所述,这正是浏览器报告的 MIME 类型不可靠的原因。