为什么 AWS 上传文字文件路径,而不是上传图像?

Why is AWS uploading literal file paths, instead of uploading images?

TL;DR

如何将文件路径输入 AWS S3 API Ruby 客户端,并将它们解释为图像,而不是字符串文字文件路径?

更多详情

我正在使用 Ruby AWS S3 客户端以编程方式上传图像。我从他们的示例启动代码中获取了这段代码,自己几乎没有修改过。参见 https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/s3-example-upload-bucket-item.html

def object_uploaded?(s3_client, bucket_name, object_key)
    response = s3_client.put_object(
      body:   "tmp/cosn_img.jpeg", # is always interpreted literally
      acl:    "public-read",
      bucket: bucket_name,
      key:    object_key
    )
    if response.etag
      return true
    else
      return false
    end
  rescue StandardError => e
    puts "Error uploading object: #{e.message}"
    return false
  end

  # Full example call:
  def run_me
    bucket_name = 'cosn-images'
    object_key =  "#{order_number}-trello-pic_#{list_config[:ac_campaign_id]}.jpeg"
    region = 'us-west-2'
    s3_client = Aws::S3::Client.new(region: region)

    if object_uploaded?(s3_client, bucket_name, object_key)
      puts "Object '#{object_key}' uploaded to bucket '#{bucket_name}'."
    else
      puts "Object '#{object_key}' not uploaded to bucket '#{bucket_name}'."
    end
  end

这有效并且能够上传到 AWS,但它只上传正文中的文件 路径,而不是实际文件本身。

单击附件时显示的文件路径link

据我从客户端文档中所见,这应该可行。 https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Client.html#put_object-instance_method

客户文档

另外,通过前端手动上传这个文件也能正常工作,所以它一定是我的代码中的一个问题。

您应该如何让 AWS 知道它应该将该文件路径解释为文件路径,而不仅仅是字符串文字?

他们的文档看起来有点奇怪而且不直接,但似乎您可能需要传入一个 file/io 对象,而不是路径。

ruby docs here有这样一个例子:

s3_client.put_object(
  :bucket_name => 'mybucket',
  :key => 'some/key'
  :content_length => File.size('myfile.txt')
) do |buffer|
  File.open('myfile.txt') do |io|
    buffer.write(io.read(length)) until io.eof?
  end
end

aws ruby sdk docs 中的另一个选项,在“从磁盘流式传输文件”下:

File.open('/source/file/path', 'rb') do |file|
  s3.put_object(bucket: 'bucket-name', key: 'object-key', body: file)
end

您有两个问题:

  1. 您在 object_uploaded? 中变量分配的末尾有逗号,这会影响变量的存储方式。删除这些。
  2. 您需要将文件引用为文件对象类型,而不是文件路径。像这样:
image = File.open("#{Rails.root}/tmp/cosn_img.jpeg")

查看下面的完整代码:

def object_uploaded?(image, s3_client, bucket_name, object_key)
  response = s3_client.put_object(
    body:   image,
    acl:    "public-read",
    bucket: bucket_name,
    key:    object_key
  )
  puts response
  if response.etag
    return true
  else
    return false
  end
rescue StandardError => e
  puts "Error uploading object: #{e.message}"
  return false
end

def run_me
  image = File.open("#{Rails.root}/tmp/cosn_img.jpeg")
  bucket_name = 'cosn-images'
  object_key =  "#{order_number}-trello-pic_#{list_config[:ac_campaign_id]}.jpeg"
  region = 'us-west-2'
  s3_client = Aws::S3::Client.new(region: region)

  if object_uploaded?(image, s3_client, bucket_name, object_key)
    puts "Object '#{object_key}' uploaded to bucket '#{bucket_name}'."
  else
    puts "Object '#{object_key}' not uploaded to bucket '#{bucket_name}'."
  end
end