S3上传后出现301永久重定向

14

我正在尝试使用carrierwave和fog宝石在Ruby on Rails上将图像上传到S3,图像已经成功上传,但是当我尝试保存包含刚刚上传的图像信息的模型时,出现了以下错误:

Excon::Errors::MovedPermanently in UserController#show
app/models/user.rb:46:in `process_image_with_key'
app/controllers/user_controller.rb:12:in `show'

<Excon::Response:0x007f97846a3c18 @body="<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>PermanentRedirect</Code><Message>The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.</Message>

用户模型:

mount_uploader :image, AvatarUploader

def image_name
  File.basename(image.path || image.filename) if image
end

def process_image_with_key( key )
  unless key.nil?
    self.key = key
    self.remote_image_url = self.image.direct_fog_url(with_path: true)
    self.save!
  end
end

AvatarUploader:

# encoding: utf-8

class AvatarUploader < CarrierWave::Uploader::Base

  include CarrierWaveDirect::Uploader

  include CarrierWave::RMagick

  # Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
  include Sprockets::Helpers::RailsHelper
  include Sprockets::Helpers::IsolatedHelper

  include CarrierWave::MimeTypes
  process :set_content_type

  version :thumb do
    process resize_to_fill: [50, 50]
  end

end

用户控制器

def show
  @user = User.find_by_id(params[:id])
  @user.process_image_with_key(params[:key])
  @uploader = User.new.image
  @uploader.success_action_redirect = user_url(@user.id)
end

carrierwave 初始化程序

CarrierWave.configure do |config|
  config.fog_credentials = {
    :provider               => 'AWS',
    :aws_access_key_id      => ENV['AWS_ACCESS_KEY_ID'],
    :aws_secret_access_key  => ENV['AWS_SECRET_ACCESS_KEY'],
    :region                 => 'us-west-1'
  }
  config.fog_directory  = ENV['AWS_FILE_BUCKET']
  config.fog_attributes = {'Cache-Control'=>'max-age=315576000'}
end

Gemfile

gem 'carrierwave'
gem 'rmagick'
gem 'fog'
gem 'carrierwave_direct'
2个回答

34
<Error><Code>PermanentRedirect</Code><Message>The bucket you are attempting to access
must be addressed using the specified endpoint. Please send all future requests to 
this endpoint.</Message></Error>

这是一个经常遇到的问题:您正在尝试访问位于区域us-west-1的存储桶,但由于传统原因,在大多数/所有AWS SDKs中,默认的Amazon S3区域为US Standard,它使用网络映射自动将请求路由到弗吉尼亚北部或太平洋西北地区的设施(有关详细信息,请参见区域和端点)。

因此,您只需要在使用S3 API之前明确指定您的存储桶区域的终端节点,例如us-west-1

  config.fog_credentials = {
    :provider               => 'AWS',
    :aws_access_key_id      => ENV['AWS_ACCESS_KEY_ID'],
    :aws_secret_access_key  => ENV['AWS_SECRET_ACCESS_KEY'],
    :region                 => 'us-west-1'
    :endpoint               => 'https://s3-us-west-1.amazonaws.com/'
  }

谢谢!它有效!但是我还没有考虑到一些问题,下面我会解释... - p1nox
顺便说一下,我在上传来自Facebook/Twitter用户的远程图像时遇到了奇怪的验证消息,不知道你是否有几分钟时间观看它 StackOverflow问题 - p1nox
1
这让我找到了答案 - 有趣的是 - 在 AWS 控制台中我的存储桶 URL 中的区域与属性下列出的区域不同 - 所以明智之举是 - 要仔细检查。这解决了我的问题。 - zero_cool
对我来说,这个最简单的答案也起作用了:https://dev59.com/mGPVa4cB1Zd3GeqP-e8c - steel
+1 @Jackson_Sandland,我遇到了完全相同的情况——对S3而言,令人眼花缭乱的是控制台的区域下拉菜单说它们无关紧要...但是对于上传来说它们确实很重要! - Gon Zifroni

1

再次感谢Steffen Opel

但是我没有考虑到一些问题,我的地区是美国标准,因此,我的carrierwave初始化器看起来像这样: # :region => # 美国标准不需要 :endpoint => 'https://s3.amazonaws.com'

这个链接就是关键:D


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接