【问题标题】:Rails Active Storage prevents upload when mime type is empty当 MIME 类型为空时,Rails Active Storage 会阻止上传
【发布时间】:2019-12-24 03:36:41
【问题描述】:

我正在使用 Rails 6 中的 Direct Upload 和 Active Storage 上传文件。在上传 .stl 文件时,我遇到了以下错误 Mime::Type::InvalidMimeType ("" is not a valid MIME type),这会导致 406 错误。

使用 JS 检查文件时,它也不会返回 Mime 类型。文件类型只是空的。

我尝试过的所有.stl 文件都是这种情况。图像文件按预期工作。

我已使用Mime::Type.register "model/stl", :stl 将正确的 Mimetype 添加到 Rails 初始化程序。但这当然没有区别。

文件是在JS中使用DirectUpload提交的。

  new DirectUpload(file, url, this)

没有文件验证。

所以基本上我的问题是;

  • 为什么 mimetype 是空的?
  • 是否有其他验证文件类型的方法?
  • 我能否以某种方式设置 mimetype 而不会导致安全问题?
  • 我能否以某种方式接受该文件,即使 mimetype 为空?

【问题讨论】:

  • 从活动存储的代码中,它使用file.type获取内容类型(github.com/rails/rails/blob/master/activestorage/app/assets/…),如果您使用开发工具调试变量,file.type返回什么?
  • @arieljuod 它是空的,只是“”。
  • 从文档 developer.mozilla.org/en-US/docs/Web/API/File/type 看来,您的浏览器(或您的系统,我不确定)不知道扩展名中的文件 mime 类型是什么(这就是它的原因空白的)。我想您可以覆盖直接上传调用的控制器操作并设置所需的 mime 类型。检查错误日志以获取控制器和操作。鉴于 file.type 返回的 mime 类型仅取决于扩展名,如果接收到的文件的扩展名是 .slt,我不会担心对该 mime 类型进行硬编码。
  • @arieljuod 很有趣,谢谢。我遇到了这个媒体类型列表:iana.org/assignments/media-types/media-types.xhtml#model。那里提到了 STL,所以我认为它应该可以工作。我已经在 Chrome 和 Firefox 中尝试过,都导致相同的错误。无论如何,您对我如何覆盖此操作有什么建议吗?目前我的控制器是非常基本的 Rails,但文件甚至没有达到这一点,所以我不确定要更改什么。控制台提到了ActiveStorage::DirectUploadsController#create。这是我可以以某种方式覆盖的东西吗?
  • 您可以创建自己的控制器来扩展 ActiveStorage::DirectUploadsController,覆盖创建操作(复制原始 github.com/rails/rails/blob/master/activestorage/app/… 并将 mime_type 设置为 content_type 参数),然后将路由更改为您的操作原版 (github.com/rails/rails/blob/master/activestorage/config/…)

标签: javascript ruby-on-rails


【解决方案1】:

所以,问题似乎是ActiveStorage使用javascripts File.type方法来确定mime类型,这不太可靠https://developer.mozilla.org/en-US/docs/Web/API/File/type(它只检查扩展名,看起来它取决于操作系统的设置) .

既然您已经知道您希望文件是什么 mime 类型,并且考虑到它已经使用了一种不太可靠的方法,我想如果文件扩展名是您想要的文件扩展名,手动设置文件类型是可以的.

为了覆盖原来的直接上传动作,你可以创建一个新的控制器来扩展原来的https://github.com/rails/rails/blob/master/activestorage/app/controllers/active_storage/direct_uploads_controller.rb。在您的自定义控制器上覆盖 create 操作并设置 params[:blob][:content_type] 的值(如果它为空),然后执行相同操作或调用 super。

要让 DirectUpload 使用您的控制器和操作,您需要更改直接上传使用的路由 https://github.com/rails/rails/blob/master/activestorage/config/routes.rb。只需使用相同的 url /direct_upload 为您的控制器添加一个新路由。

【讨论】:

    【解决方案2】:

    只是为了澄清 arieljuod 回答的最后一段:

    源路由有前缀;您的覆盖路线必须包含完整路径。例如,要覆盖默认的创建操作:

    post "/rails/active_storage/direct_uploads" => "your_controller_name#create"
    

    【讨论】:

      猜你喜欢
      • 2020-02-01
      • 2022-11-11
      • 1970-01-01
      • 2021-09-04
      • 1970-01-01
      • 2022-12-10
      • 2013-05-24
      • 1970-01-01
      相关资源
      最近更新 更多