简体   繁体   English

当 MIME 类型为空时,Rails Active Storage 会阻止上传

[英]Rails Active Storage prevents upload when mime type is empty

I'm uploading a file using Direct Upload and Active Storage in Rails 6. When uploading a .stl file I am met with the following error Mime::Type::InvalidMimeType ("" is not a valid MIME type) which results in a 406 error.我正在使用 Rails 6 中的 Direct Upload 和 Active Storage 上传文件。上传.stl文件时,我遇到以下错误Mime::Type::InvalidMimeType ("" is not a valid MIME type)这导致406 错误。

When checking the file with JS it does also not return a Mime type.使用 JS 检查文件时,它也不会返回 Mime 类型。 The file type is simply empty.文件类型只是空的。

This is the case for all .stl files I've tried.我尝试过的所有.stl文件都是这种情况。 Image files work as expected.图像文件按预期工作。

I've added the correct Mimetype to a rails initializer using Mime::Type.register "model/stl", :stl .我已经使用Mime::Type.register "model/stl", :stl添加了正确的 Mimetype 到 rails 初始值设定项。 But of course this makes no difference.但这当然没有区别。

The file is submitted in JS using DirectUpload.该文件使用 DirectUpload 在 JS 中提交。

  new DirectUpload(file, url, this)

There is no file validation.没有文件验证。

So essentially my questions are;所以基本上我的问题是;

  • Why is the mimetype empty?为什么 mimetype 是空的?
  • Is there a different way of verifying the filetype?是否有不同的方式来验证文件类型?
  • Can I somehow set the mimetype without causing security issues?我可以在不引起安全问题的情况下以某种方式设置 mimetype 吗?
  • Can I somehow accept the file anyway, even if the mimetype is empty?即使 mimetype 为空,我也可以以某种方式接受该文件吗?

So, the problem seems to be that ActiveStorage uses javascripts File.type method to determine the mime type, which is not too reliable https://developer.mozilla.org/en-US/docs/Web/API/File/type (it only checks the extension and it looks like it depends on the operating system's settings).所以,问题似乎是 ActiveStorage 使用 javascripts File.type 方法来确定 mime 类型,这不是太可靠https://developer.mozilla.org/en-US/docs/Web/API/File/type (它只检查扩展名,看起来它取决于操作系统的设置)。

Since you already know what mime type you want the file to be and given that it already uses a not too reliable method, I guess it's ok to set the file type manually if the file extension is the one you are expeting to be.由于您已经知道您想要文件的 MIME 类型,并且考虑到它已经使用了一种不太可靠的方法,我想如果文件扩展名是您想要的文件类型,那么手动设置文件类型是可以的。

In order to override the original direct upload action, you can create a new controller to extend the original https://github.com/rails/rails/blob/master/activestorage/app/controllers/active_storage/direct_uploads_controller.rb .为了覆盖原来的直接上传动作,你可以创建一个新的控制器来扩展原来的https://github.com/rails/rails/blob/master/activestorage/app/controllers/active_storage/direct_uploads_controller.rb On your custom controller override the create action and set the value of params[:blob][:content_type] if it's empty and then just do the same or call super.在您的自定义控制器上覆盖create操作并设置params[:blob][:content_type]如果它为空),然后执行相同操作或调用 super。

For DirectUpload to use your controller and action, you need to change the route that direct upload uses https://github.com/rails/rails/blob/master/activestorage/config/routes.rb .为了让 DirectUpload 使用您的控制器和动作,您需要更改直接上传使用的路由https://github.com/rails/rails/blob/master/activestorage/config/routes.rb Just add a new route for your controller using the same url /direct_upload .只需使用相同的 url /direct_upload为您的控制器添加一个新路由。

Just to clarify the closing paragraph of arieljuod's answer:只是为了澄清 arieljuod 答案的最后一段:

The source route is prefixed;源路由带有前缀; your overriding route must include the full path.您的覆盖路线必须包含完整路径。 For instance, to override the default create action:例如,要覆盖默认的创建操作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM