mp4 和 js 的不正确 mime-type(content-type 头)

你好!

我刚注意到 discourse 为几种文件类型设置了不正确的 Content-type 标头:
来自 /uploads/ 的 mp4 文件使用 content-type: application/mp4 而不是 video/mp4
我的上传来自 S3,这取决于 S3 托管提供商。

一些 JavaScript(.js)文件,例如来自 /brotli_asset/ 的文件,使用 application/javascript 而不是 text/javascript。

我使用的是未经修改的 discourse_docker,我已经检查了包含的 nginx,它包含正确的 mime-types 配置文件。看起来是 discourse 后端负责发送这些不正确的 mime-types。

您好!据我所知,上传问题是我这边 S3 提供商(我已通过覆盖 nginx 中的设置成功解决)造成的。而 /brotli_asset/ 的 JS 问题似乎是 discourse 的“内部”nginx 中存在某种问题,看起来是 discourse_docker 的一个 bug。
很抱歉,我没能找到比论坛这部分更好的地方来报告 bug。您能指点一下吗?

这里就是正确的地方,你没找错。

你能解释一下为什么这是一个我们应该关心的问题吗?它会破坏什么吗?

简而言之,Discourse 从不同位置发送具有不同 mime 类型的 JavaScript。例如,/theme-javascripts/ff3c633d0d4192c83a194066eaa9d823b5c2d8f6.js 使用 text/javascript(正确),而之前提到的 /brotli_asset/... 使用 application/javascript。这可能会让 Discourse 和客户端之间的代理服务器以及我注意到问题的分析系统感到困惑。

看起来您只需要正确设置 Discourse Docker 镜像中的内部 Nginx 以支持 Brotli 资源。

你能说出因此而中断的代理/分析系统吗?分享一个实际发生问题的例子?

在我的 goaccess 报告中,discourse 的 mime-types 仪表板将 js 的值拆分了:一个用于 text/javascript,另一个用于 application/javascript。

第二个:nginx 中的 gzip_types 和 brotli_types 指令都由 mime-types 操作。因此,对于 discourse,人们必须同时设置正确的 text/javascript 和不正确的 application/javascript。

对于任何基于 mime-type 重新压缩内容的代理也是如此。

我在此主题下跟帖,因为我认为这会造成一个小问题,或者至少是不受欢迎的行为。

在 Discourse 上打开托管的视频文件会强制下载视频,而不是在浏览器中播放。

右键单击,复制视频地址,将链接粘贴到浏览器的地址栏。

奇怪的是,在本地开发安装中,视频可以在浏览器中正常播放:

加载视频 URL 时,常规安装和开发安装之间的标头不同。

在常规生产安装中,视频内容类型设置为 application/mp4,而在开发安装中则设置为 video/mp4

已将 Discourse send PDF inline 的内容交叉发布过来,因为作者修复了 PDF 类似的非预期行为。

如果有人有防止 mp4 被强制下载的解决方案,我洗耳恭听。

4 个赞

哦,好发现——这很奇怪。

看起来 MiniMime(我们使用并拥有的一个库)可能会返回这些值

pry(main)> MiniMime.lookup_by_filename("a.mp4").content_type
=> "application/mp4"

我将创建一个 PR,然后讨论更改这些值是否会成为一个问题。

5 个赞

只是一个快速更新 -

上面我们使用的 ext_mime_db 遵循 IANA 媒体类型,定义在此 -
https://www.iana.org/assignments/media-types/media-types.xhtml。不幸的是,这意味着 mp4 正确的 MIME 类型是 application/mp4 :sweat_smile:


不过,进一步查看我们的 S3 上传器实现,我确实看到我们为几乎所有非图像上传都添加了 Content-Disposition 标头 \"attachment\",但感觉它最初只打算为 svg 添加。使用 \"attachment\" 会导致内容被下载而不是在新标签页中打开。对于视频,application/videoattachment 的混合使用是导致此问题的原因。

我认为我们至少可以删除这个标头。

2 个赞

不太确定是否完全理解,所以有一个关于此 PR 的快速问题 :person_raising_hand:

为什么修改专门针对 s3 相关文件,而即使不使用 s3 也会发生强制下载? :thinking:

这总的来说能解决问题吗?
这也能解决浏览器中可打开的其他文件(如 PDF)的强制下载问题吗?

上传到 S3 时,我们必须指定诸如文件的 Content-DispositionContent-Type 之类的标头。这些是在加载文件时将返回的值 - PutObject - Amazon Simple Storage Service

你能解释一下这是什么时候发生的吗?

PR 将删除 Content-Disposition: attachment 标头,该标头会强制下载,无论您使用什么浏览器。

升级您的网站后,将使用 Content-Type,浏览器将决定如何处理它。需要注意的一点是,Safari 和 Firefox 没有 Content-Type: application/mp4 的问题,但在 Chrome 上,它仍然会强制下载(可能是因为 Chrome 在 mp4 文件类型方面有一些不好的历史记录)。

2 个赞