浏览器如何确定上传文件的 MIME 类型? [英] How is mime type of an uploaded file determined by browser?

查看:42
本文介绍了浏览器如何确定上传文件的 MIME 类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Web 应用程序,用户需要在其中上传 .zip 文件.在服务器端,我正在检查上传文件的 MIME 类型,以确保它是 application/x-zip-compressedapplication/zip.

这对我来说在 Firefox 和 IE 上运行良好.但是,当一位同事对其进行测试时,他在 Firefox 上失败了(发送的 MIME 类型类似于application/octet-stream"),但在 Internet Explorer 上可以正常工作.我们的设置似乎相同:IE8、FF 3.5.1 禁用所有附加组件、Win XP SP3、WinRAR 作为本机 .zip 文件处理程序安装(不确定是否相关).

所以我的问题是:浏览器如何确定要发送的 MIME 类型?

请注意:我知道 mime 类型是由浏览器发送的,因此不可靠.我只是为了方便而检查它 - 主要是为了提供比尝试将非 zip 文件作为 zip 文件打开时获得的错误消息更友好的错误消息,并避免加载(可能很重的)zip 文件库.

解决方案

Chrome

Chrome (撰写本文时为 38 版) 有 3 种方法可以确定 MIME 类型,并按特定顺序进行.下面的代码片段来自文件 src/net/base/mime_util.cc,方法 MimeUtil::GetMimeTypeFromExtensionHelper.

//我们实现了与 Mozilla 相同的算法,用于将文件扩展名映射到//一个 mime 类型.也就是说,我们首先检查一个硬编码列表(它不能被//覆盖),然后如果在那里找不到,我们将遵循系统注册表.//最后,我们扫描一个二级硬编码列表来捕获我们可以识别的类型//推断但我们也希望允许操作系统覆盖.

硬编码列表在文件中出现得更早一些:https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=170(kPrimaryMappingskSecondaryMappings).

示例:从安装了 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 版) 以类似的方式工作.来自文件 uriloaderexthandler sExternalHelperAppService.cpp 的片段,方法 nsExternalHelperAppService::GetTypeFromExtension

//好的.我们想按以下顺序尝试以下 mimetype 信息来源://1. defaultMimeEntries 数组//2. 用户设置首选项(由处理程序服务管理)//3. 操作系统提供的信息//4. 我们的额外"大批//5. 来自插件的信息//6. ext-to-type-mapping"类别

硬编码列表位于文件中较早的位置,靠近第 441 行.您正在寻找 defaultMimeEntriesextraMimeEntries.

使用我当前的配置文件,浏览器将报告 text/csv,因为在 mimeTypes.rdf(上面列表中的第 2 项)中有一个条目.使用没有此条目的新配置文件,浏览器将报告 application/vnd.ms-excel(列表中的第 3 项).

总结

浏览器中的硬编码列表非常有限.通常,浏览器发送的 MIME 类型将是操作系统报告的类型.这就是为什么,如问题所述,浏览器报告的 MIME 类型不可靠.

I have a web app where the user needs to upload a .zip file. On the server-side, I am checking the mime type of the uploaded file, to make sure it is application/x-zip-compressed or application/zip.

This worked fine for me on Firefox and IE. However, when a coworker tested it, it failed for him on Firefox (sent mime type was something like "application/octet-stream") but worked on Internet Explorer. Our setups seem to be identical: IE8, FF 3.5.1 with all add-ons disabled, Win XP SP3, WinRAR installed as native .zip file handler (not sure if that's relevant).

So my question is: How does the browser determine what mime type to send?

Please note: I know that the mime type is sent by the browser and, therefore, unreliable. I am just checking it as a convenience--mainly to give a more friendly error message than the ones you get by trying to open a non-zip file as a zip file, and to avoid loading the (presumably heavy) zip file libraries.

解决方案

Chrome

Chrome (version 38 as of writing) has 3 ways to determine the MIME type and does so in a certain order. The snippet below is from file src/net/base/mime_util.cc, method 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.

The hard-coded lists come a bit earlier in the file: https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=170 (kPrimaryMappings and kSecondaryMappings).

An example: when uploading a CSV file from a Windows system with Microsoft Excel installed, Chrome will report this as application/vnd.ms-excel. This is because .csv is not specified in the first hard-coded list, so the browser falls back to the system registry. HKEY_CLASSES_ROOT.csv has a value named Content Type that is set to application/vnd.ms-excel.

Internet Explorer

Again using the same example, the browser will report application/vnd.ms-excel. I think it's reasonable to assume Internet Explorer (version 11 as of writing) uses the registry. Possibly it also makes use of a hard-coded list like Chrome and Firefox, but its closed source nature makes it hard to verify.

Firefox

As indicated in the Chrome code, Firefox (version 32 as of writing) works in a similar way. Snippet from file uriloaderexthandler sExternalHelperAppService.cpp, method 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

The hard-coded lists come earlier in the file, somewhere near line 441. You're looking for defaultMimeEntries and extraMimeEntries.

With my current profile, the browser will report text/csv because there's an entry for it in mimeTypes.rdf (item 2 in the list above). With a fresh profile, which does not have this entry, the browser will report application/vnd.ms-excel (item 3 in the list).

Summary

The hard-coded lists in the browsers are pretty limited. Often, the MIME type sent by the browser will be the one reported by the OS. And this is exactly why, as stated in the question, the MIME type reported by the browser is unreliable.

这篇关于浏览器如何确定上传文件的 MIME 类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆