我想允许用户上传.jpg
文件,但前提是它们实际上是.jpg
的(例如,cat.gif
重命名为cat.jpg
不起作用。
目前在我的Carrierwave ImageUploader.rb
中,我有:
include CarrierWave::RMagick
include CarrierWave::MimeTypes
process :set_content_type
def extension_white_list
%w(jpg jpeg png)
end
在我的 Rspec 测试文件中,我以三种方式对其进行了测试:
# Works
describe "with invalid mime type and invalid extension" do
before do
image.image = File.open(File.join(Rails.root, 'spec', 'support', 'image', 'images', 'executable.jpg')) # this is a .exe renamed to .jpg
end
it { image.should_not be_valid }
end
# Works
describe "with invalid mime type and invalid extension" do
before do
image.image = File.open(File.join(Rails.root, 'spec', 'support', 'image', 'images', 'test_gif.gif')) # this is a .gif
end
it { should_not be_valid }
end
# Doesn't work
describe "with invalid mime type and valid extension" do
before do
image.image = File.open(File.join(Rails.root, 'spec', 'support', 'image', 'images', 'test_gif.jpg')) # this is a .gif renamed to .jpg
end
it { image.should_not be_valid }
end
前两个测试通过,但第二个测试失败。我不知道为什么,因为我在白名单上没有gif
,我正在检查 MIME 类型。
有什么建议吗?
(将 gif 转换为 jpg 是我的备份,但我宁愿拒绝它们。
我遇到了同样的问题,不得不覆盖上传者的默认set_content_type方法。这假设您的 Gemfile 中有 Rmagick gem,以便您可以通过读取图像获得正确的 mime 类型,而不是做出最佳猜测。
注意:如果仅支持 JPG 和 PNG 图像的 Prawn 正在使用图像,则此功能特别有用。
上传器类:
process :set_content_type
def set_content_type #Note we are overriding the default set_content_type_method for this uploader
real_content_type = Magick::Image::read(file.path).first.mime_type
if file.respond_to?(:content_type=)
file.content_type = real_content_type
else
file.instance_variable_set(:@content_type, real_content_type)
end
end
图像模型:
class Image < ActiveRecord::Base
mount_uploader :image, ImageUploader
validates_presence_of :image
validate :validate_content_type_correctly
before_validation :update_image_attributes
private
def update_image_attributes
if image.present? && image_changed?
self.content_type = image.file.content_type
end
end
def validate_content_type_correctly
if not ['image/png', 'image/jpg'].include?(content_type)
errors.add_to_base "Image format is not a valid JPEG or PNG."
return false
else
return true
end
end
end