我需要使用 Content-Type: application/octet-stream 来进行文件下载吗?

602

HTTP标准中提到:

如果在应用了 Content-Disposition: attachment 头部字段的响应中,同时使用了 application/octet-stream 内容类型,则建议用户代理程序不要显示响应,而是直接弹出“另存为”对话框。

我理解为:

Content-Type: application/octet-stream
Content-Disposition: attachment

但我原本认为 Content-Type 应该是 application/pdfimage/png 等。

如果我想让浏览器下载文件,那么我应该使用 Content-Type: application/octet-stream 吗?

1个回答

1354

不。

如果您知道内容的类型,请将Content-Type设置为它本应该是的类型。在RFC 2046中,application/octet-stream被定义为“任意二进制数据”,在这种情况下,它适用于唯一预期目的是保存到磁盘并从此以后不再与"网页"有关的实体,或者可以换个角度看; 可以安全地使用application/octet-stream的唯一方式是将其保存到文件中,并希望其他人知道它的用途。

您可以将Content-Disposition与其他content-type结合使用,例如image/png甚至text/html,以表示您希望保存而不是显示。以前在text/html的情况下,某些浏览器会忽略它,但我认为这已经是很久以前的事情了(而且我马上就要睡觉了,所以我现在不想开始测试大量的浏览器;也许过一会儿再测试吧)。

RFC 2616还提到了扩展标记的可能性,现在大多数浏览器都认识inline,表示您确实希望显示该实体(即,如果它是浏览器知道如何显示的类型,则显示;否则,浏览器无法显示)。当然,默认行为本来就是这样,但这意味着您可以包含标题的filename部分,浏览器将使用它作为建议(也许还要进行一些调整,以使文件扩展名与所涉及的content-type的本地系统规范相匹配,或者也许不需要)如果用户尝试保存。

因此:

Content-Type: application/octet-stream
Content-Disposition: attachment; filename="picture.png"

意思是“我不知道这是什么东西。请将它保存为文件,最好命名为picture.png”。

Content-Type: image/png
Content-Disposition: attachment; filename="picture.png"

意为“这是一个PNG图像,请将其保存为文件,最好命名为picture.png”。

Content-Type: image/png
Content-Disposition: inline; filename="picture.png"

意思是“这是一张PNG图片,请显示它,除非您不知道如何显示PNG图像。否则,如果用户选择保存它,我们建议将其命名为picture.png”。

那些认识inline的浏览器中,有些浏览器总是使用它,而另一些浏览器则仅在用户选择“另存为链接”但未选择在查看时选择“保存”时使用它(至少以前IE就是这样,可能几年前已经改变了)。


12
如果客户想要保存它,那么发送什么头信息都无所谓(您可以在浏览器上“保存”或“另存为”任何内容),因为头信息只是信息,而不是规则,所以“attachment”可以被视为“最好不要自己显示”,而“inline”则可以视为“如果可以的话最好自己显示”。无论哪种方式,大多数浏览器都会使用文件名值作为建议的文件名,但用户始终可以覆盖它。 - Jon Hanna
1
对我来说,这很简单,只有三点。其他答案建议使用无意义application/octet-stream Content-Type来下载文件。你不需要这样做。他们还建议将attachment设置为Content-Disposition。你也不需要这样做。你的解释让我感到清晰和舒适,而他们的则没有。 - Lewis
2
我刚刚遇到了带有BOM(字节顺序标记)文本文件的问题。众所周知,为了使Excel在CSV文件中显示国际符号,您必须将CSV编码为带有BOM的UTF16 LE。因此,我将文件发送为“text / csv”,但无法打开它。结果发现,HTTP客户端正在进行一些额外的重新编码并用垃圾替换BOM。唯一的方法是指定“binary / octet-stream”来防止此情况发生。我还没有尝试过“application / octet-stream”,因为“binary”似乎更明确地说明了我想要实现的内容。 - JustAMartin
7
大多数情况下都是这样操作的,但是iOS13/iOS14 Safari在当前标签页中打开PDF文件(仅限PDF格式)。需要将其设置为“octet-stream”才能弹出下载窗口。 - suyuan xu
3
这个不起作用。我已经尝试将Content-Type设置为text/csvapplication/octet-stream,并且都带有Content-Disposition: attachment; filename=<filename>,但是当从FE调用此API时,它不起作用。这个API是一个POST请求。浏览器在网络选项卡中显示了正确的响应,但它既不提示下载,也不自动保存文件。 - y_159
显示剩余5条评论

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