阿克舒利,您可以:
# minimal example,
# here using mongoid, but it doesn't really matter
class Media
field :filename, type: String # i.e. "cute-puppy"
field :extension, type: String # i.e. "mp4"
mount_uploader :media, MediaUploader
end
class MediaUploader < CarrierWave::Uploader::Base
# Files on S3 are only accessible via signed URLS:
@fog_public = false
# Signed URLS expire after ...:
@fog_authenticated_url_expiration = 2.hours # in seconds from now, (default is 10.minutes)
# MIME-Type and filename that the user will see:
def fog_attributes
{
"Content-Disposition" => "attachment; filename*=UTF-8''#{model.filename}",
"Content-Type" => MIME::Types.type_for(model.extension).first.content_type
}
end
# ...
end
然后产生的 urlmodel.media.url
将返回以下标头:
Accept-Ranges:bytes
Content-Disposition:attachment; filename*=UTF-8''yourfilename.mp4
Content-Length:3926746
Content-Type:video/mpeg
Date:Thu, 28 Feb 2013 10:09:14 GMT
Last-Modified:Thu, 28 Feb 2013 09:53:50 GMT
Server:AmazonS3
...
然后浏览器将强制下载(而不是在浏览器中打开)并使用您设置的文件名,而不管用于在存储桶中存储内容的文件名是什么。唯一的缺点是 Content-Disposition 标头是在 Carrierwave 创建文件时设置的,因此您不能例如在同一个文件上为不同的用户使用不同的文件名。
在这种情况下,您可以使用 RightAWS 生成签名 URL:
class Media
def to_url
s3_key = "" # the 'path' to the file in the S3 bucket
request_header = {}
response_header = {
"response-content-disposition" => "attachment; filename*=UTF-8''#{filename_with_extension}",
"response-content-type" => MIME::Types.type_for(extension).first.content_type
}
RightAws::S3Generator.new(
Settings.aws.key,
Settings.aws.secret,
:port => 80,
:protocol => 'http').
bucket(Settings.aws.bucket).
get(s3_key, 2.hours, request_header, response_header)
end
end
编辑:没有必要使用 RightAWS,uploader#url
支持覆盖响应标头,语法有点混乱(就像 CarrierWave 的所有内容一样,恕我直言,但它仍然很棒):
Media.last.media.url(query: {"response-content-disposition" => "attachment; filename*=UTF-8''huhuhuhuhu"})
# results in:
# => https://yourbucket.s3.amazonaws.com/media/512f292be75ab5a46f000001/yourfile.mp4?response-content-disposition=attachment%3B%20filename%2A%3DUTF-8%27%27huhuhuhuhu&AWSAccessKeyId=key&Signature=signature%3D&Expires=1362055338