未知文件类型 MIME?

177

如果上传的文件没有扩展名,我是否必须指定MIME类型?换句话说,是否有默认的通用MIME类型?

3个回答

221

对于未知类型,您可以使用application/octet-stream

RFC 2046在第4.5.1节中说明:

"octet-stream"子类型用于表示主体包含任意二进制数据。


4
根据RFC规范,对于未知的数据类型,你不应该发送任何类型信息。RFC-2046只定义了已知的类型,但RFC-7231告诉你如何处理未知的类型。 - Sampo Sarrala - codidact.org
@SampoSarrala 我有点不同的理解 RFC-7231:「如果 Content-Type 头字段不存在,接收方可以假定为 "application/octet-stream"([RFC2046] 第 4.5.1 节),或者检查数据以确定其类型。」我理解为我们应该不发送 Content-Type 或者如果我们不想让客户端进行内容检查猜测游戏,那么将 application/octet-stream 作为默认值是安全的。 - Jpnh
1
@Jpnh 是的,没错。当不知道内容类型时,Content-Type头应该不存在。也可以发送application/octet-stream,这基本上告诉客户端“_你现在不想显示它,但继续保存这些字节到文件中_”。这使得Web客户端提供了保存文件的选项。选项1 == 不知道这个文件的任何信息。选项2 == 文件内容不能使用MIME描述,或者只能保存到磁盘。实际上,任何一种选项都是正确的。我应该选择更好的措辞来避免混淆。 - Sampo Sarrala - codidact.org
5
“任意二进制数据”不等于“未知数据”。通过使用application/octet-stream,您告诉浏览器内容类型已知,不是文本也不是图像,而是任意的二进制数据,因此应该下载到文件并可能被执行。这不仅是错误的,而且是一个安全漏洞,特别是考虑到现代下载管理器几乎不可见。正确的答案是没有content-type头部。如果您不知道文件类型,浏览器可能会知道,所以让它来猜测,尤其是当它知道使用上下文时(图像、文档、脚本等)。 - FF_Dev
1
@FF_Dev 我相信那是胡说八道。"任意二进制数据"并不意味着"可执行";浏览器(或下载管理器)没有理由假设application/octet-stream文件是可执行的。即使浏览器确实在有意识地下载可执行文件,它也不会在未经用户同意的情况下"可能执行"它;仅仅下载一个可执行文件并不意味着我想要立即执行它。如果真的有一个浏览器可能会在下载时自动执行application/octet-stream文件,请告诉我们是哪个浏览器,以及如何重现这种行为。现在我不相信你。 - Mark Amery
显示剩余7条评论

57

RFC资源:

我们应该使用RFC-7231(HTTP/1.1语义和内容)作为参考,而不是RFC-2046(媒体类型),因为问题明确涉及到HTTP内容类型。

RFC-2046也没有清楚地定义未知类型,但RFC-7231有。

简短回答:

不要为未知数据发送MIME类型。
更明确地说:根本不要使用Content-Type头。

参考资料:

RFC-7231
超文本传输协议(HTTP/1.1):语义和内容
3.1.1.5。 内容类型

生成包含有效负载正文的消息的发送方应在该消息中生成Content-Type标头字段,除非封闭表示的预期媒体类型对发送方未知。

该部分明确告诉您如果您不确定,可以省略它。 它还指出接收者可以假设类型为application/octet-stream,但实际情况可能是其他东西。

那么有什么不同呢?

RFC-2046
4.5.1。 二进制流子类型

对于接收“application/octet-stream”实体的实现,推荐的操作是仅向用户提供将数据放入文件中的选项,取消任何Content-Transfer-Encoding,或者可能将其用作用户指定的处理过程的输入。

正如上面已经声明的那样:

RFC-7231
3.1.1.5。 内容类型

如果没有Content-Type头字段,则接收方可以假定它为应用程序/八位字节流,但实际情况可能是其他东西。

可以假设媒体类型为"application/octet-stream"([RFC2046], Section 4.5.1),或者检查数据以确定其类型。 如果将其定义为"application/octet-stream",则表明您知道它是"application/octet-stream"。 如果不定义,则表明您不知道它是什么,并将决定权留给接收器,接收器可以检查它是否像鸭子一样...

1
这个答案值得点赞,因为它是唯一的真相。此外,默认情况下使用“application/octet-stream”会使大多数浏览器触发下载,考虑到几乎看不见的现代下载管理器,这是一个安全漏洞。 - FF_Dev
1
这对于HTTP是正确的,但问题是关于MIME的一般性,而不是关于HTTP的。例如,在电子邮件中,规则完全不同。请参见建议的重复https://dev59.com/iWcs5IYBdhLWcg3w1XbZ的讨论。 - tripleee
我出于同样的原因给了一个赞,但我同意FF_Dev的观点。除非意图是“application/octet-stream”并触发下载,否则需要“application/unknown”。如果“Content-Disposition”未设置,则浏览器不尝试下载文件会很好,但有太多的网站在没有设置文件名的情况下随意下载文件。特别是银行。 - justdan23

19

我更喜欢使用application/unknown,但结果肯定与application/octet-stream相同。


19
有没有标准允许使用"application/unknown"代替"application/octet-stream"? - Hendrik Brummermann
3
谢谢!application/unknown 运行得很好,但 octet-stream 在我的样本 PNG 文件中在 Chrome 中会出现错误。请问需要怎么处理? - fnkr
11
为什么要将 .png 文件作为 “application/octet-stream” 或 “application/unknown” 进行传输呢?毕竟已经有了“image/png”的格式。 - Aidiakapi
10
@jenson-button-event 这与重新发明轮子无关。MIME类型指定了您的意图。如果您知道发送的内容应该是png图像,请传递该信息。如果字节码意外表示为jpeg格式,则您的应用程序可以警告您它不是有效的png格式,并且Bug可能在其他地方。此外,并非所有应用程序都像浏览器一样强大和容错。它们被设计用于修复程序员的错误,但这远非唯一目的。浏览器并不是使用MIME类型的唯一应用程序。 - Aidiakapi
3
你的参考是什么?未知类型不提供有关文件内容或状态甚至是二进制还是基于文本的任何信息,对于生产代码来说太模糊了,对于小项目可能还可以,因为如果文件MIME类型在操作系统中没有处理程序,则它本质上是可下载的二进制文件-而unknown类型是Windows操作系统中已知的句柄,您可以分配一个操作(例如使用记事本打开未知文件)。虽然这是不好的做法,但您可以将未知类型与结合使用以跳过任何执行 :/ - user257319
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接