[英]Detect MIME type of uploaded file in Ruby
是否有防彈方法來檢測 Ruby 或 Ruby on Rails 中上傳文件的 MIME 類型? 我正在使用 SWFupload 上傳 JPEG 和 PNG, content_type
始終是"application/octet-stream"
ruby-filemagic gem 可以做到:
require 'filemagic'
puts FileMagic.new(FileMagic::MAGIC_MIME).file(__FILE__)
# => text/x-ruby; charset=us-ascii
這個 gem 根本不看文件擴展名。 它讀取一些文件內容並使用它來猜測文件的類型。
在 Ruby on Rails 中,您可以執行以下操作:
MIME::Types.type_for("filename.gif").first.content_type # => "image/gif"
您可以根據文件的魔術頭使用這種可靠的方法:
def get_image_extension(local_file_path)
png = Regexp.new("\x89PNG".force_encoding("binary"))
jpg = Regexp.new("\xff\xd8\xff\xe0\x00\x10JFIF".force_encoding("binary"))
jpg2 = Regexp.new("\xff\xd8\xff\xe1(.*){2}Exif".force_encoding("binary"))
case IO.read(local_file_path, 10)
when /^GIF8/
'gif'
when /^#{png}/
'png'
when /^#{jpg}/
'jpg'
when /^#{jpg2}/
'jpg'
else
mime_type = `file #{local_file_path} --mime-type`.gsub("\n", '') # Works on linux and mac
raise UnprocessableEntity, "unknown file type" if !mime_type
mime_type.split(':')[1].split('/')[1].gsub('x-', '').gsub(/jpeg/, 'jpg').gsub(/text/, 'txt').gsub(/x-/, '')
end
end
ruby-filemagic gem 是一個很好的解決方案,但需要額外依賴libmagic (最近作為CarrierWave::MagicMimeTypes刪除的一部分從 CarrierWave 中刪除)。
如果您對純 ruby 實現感興趣,請考慮MimeMagic gem! 它適用於 freedesktop.org mime 數據庫中列出的文件類型:
require 'mimemagic'
MimeMagic.by_magic(File.open('Table-Flip-Guy.jpg')).type # => "image/jpeg"
對於 Microsoft Office 2007+ 格式(xlsx、docx 和 pptx),需要覆蓋(除非您同意這些文件的通用“應用程序/zip”MIME 類型)
require 'mimemagic'
require 'mimemagic/overlay'
MimeMagic.by_magic(File.open('big_spreadsheet.xlsx')).type # => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
filemagic gem 是很好的解決方案,但依賴於許多不必要的 gem。 (rails, aws-sdk-core, ...)
如果您的應用程序很小並且僅在 Linux 或 OSX 中運行,請考慮使用file
程序:
require 'shellwords'
mimetype = `file --brief --mime-type - < #{Shellwords.shellescape(__FILE__)}`.strip
注意:用任何包含文件路徑的 expr 替換__FILE__
。
截至 2021 年,我認為根據所有可用提示(幻數、幻數不足時的文件名、用戶提示)計算 MIME 類型的最佳工具是Marcel 。
無恥地引用文檔本身:
Marcel::MimeType.for Pathname.new("example.gif")
# => "image/gif"
File.open "example.gif" do |file|
Marcel::MimeType.for file
end
# => "image/gif"
Marcel::MimeType.for Pathname.new("unrecognisable-data"), name: "example.pdf"
# => "application/pdf"
Marcel::MimeType.for extension: ".pdf"
# => "application/pdf"
Marcel::MimeType.for Pathname.new("unrecognisable-data"), name: "example", declared_type: "image/png"
# => "image/png"
Marcel::MimeType.for StringIO.new(File.read "unrecognisable-data")
# => "application/octet-stream"
mimemagic gem 也會這樣做
https://github.com/minad/mimemagic
來自官方文檔
MimeMagic 是一個通過擴展名或內容來檢測文件的 MIME 類型的庫。 它使用由 freedesktop.org 提供的 mime 數據庫(參見http://freedesktop.org/wiki/Software/shared-mime-info/ )。
require 'mimemagic' MimeMagic.by_extension('html').text? MimeMagic.by_extension('.html').child_of? 'text/plain' MimeMagic.by_path('filename.txt') MimeMagic.by_magic(File.open('test.html')) # etc...
如果您是從頭開始執行此操作,請安裝 mimemagic gem
gem 'mimemagic'
打開流(目標圖像的字節數)
url="https://i.ebayimg.com/images/g/rbIAAOSwojpgyQz1/s-l500.jpg"
result = URI.parse(url).open
然后檢查數據流的文件類型,例如:
MimeMagic.by_magic(result).type == "image/jpeg"
即使如上所述
%w(JPEG GIF TIFF PNG).include?(MimeMagic.by_magic(result).type)
這可能更優雅
你可以使用
Mime::Type.lookup_by_extension(extention_name)
謝謝
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.