我遇到了同样的问题,花了太长时间才找到答案!事实证明,当您设置fog_public = false CarrierWave 将忽略config.asset_host。您可以通过设置config.fog_public = true进行演示:您的 URL 现在将是 CloudFront URL,而不是 S3 URL。之前有人提出过这个问题:
https://github.com/carrierwaveuploader/carrierwave/issues/1158
https://github.com/carrierwaveuploader/carrierwave/issues/1215
在最近的一个项目中,我很高兴使用 CarrierWave 处理上传到 S3,但希望它在使用Model.attribute_url时返回签名的 CloudFront URL 。我想出了以下(诚然丑陋的)解决方法,我希望其他人可以从中受益或改进:
将“cloudfront-signer” gem 添加到您的项目并按照说明进行配置。然后在config/initializers的新文件中添加以下/lib/carrierwave/uploader/url.rb覆盖(注意AWS::CF::Signer.sign_url的多次插入):
module CarrierWave
module Uploader
module Url
extend ActiveSupport::Concern
include CarrierWave::Uploader::Configuration
include CarrierWave::Utilities::Uri
##
# === Parameters
#
# [Hash] optional, the query params (only AWS)
#
# === Returns
#
# [String] the location where this file is accessible via a url
#
def url(options = {})
if file.respond_to?(:url) and not file.url.blank?
file.method(:url).arity == 0 ? AWS::CF::Signer.sign_url(file.url) : AWS::CF::Signer.sign_url(file.url(options))
elsif file.respond_to?(:path)
path = encode_path(file.path.gsub(File.expand_path(root), ''))
if host = asset_host
if host.respond_to? :call
AWS::CF::Signer.sign_url("#{host.call(file)}#{path}")
else
AWS::CF::Signer.sign_url("#{host}#{path}")
end
else
AWS::CF::Signer.sign_url((base_path || "") + path)
end
end
end
end # Url
end # Uploader
end # CarrierWave
然后通过将以下内容添加到同一文件的底部来覆盖/lib/carrierwave/storage/fog.rb :
require "fog"
module CarrierWave
module Storage
class Fog < Abstract
class File
include CarrierWave::Utilities::Uri
def url
# Delete 'if statement' related to fog_public
public_url
end
end
end
end
end
最后,在config/initializers/carrierwave.rb中:
config.asset_host = " http://d12345678.cloudfront.net "
config.fog_public = false
而已。您现在可以使用 Model.attribute_url,它会将签名的 CloudFront URL 返回到由 CarrierWave 上传到您的 S3 存储桶的私有文件。