You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么AWS S3 Ruby客户端上传的是文件路径而非实际图片?

解决方案

问题根源

AWS Ruby SDK 的 put_object 方法的 body 参数如果接收字符串类型值,会直接将字符串本身作为上传对象的内容,不会自动将其解析为本地文件路径读取对应文件内容,这就是你上传后只得到路径文本的原因。

修正方法

方案1:修改现有 put_object 写法

你需要将body参数改为传入文件IO对象,同时建议补充content_type参数明确指定文件MIME类型,保证S3返回正确的资源类型,浏览器可以直接预览图片而不是下载:

def object_uploaded?(s3_client, bucket_name, object_key)
  # 如果是Rails项目可以用 Rails.root.join("tmp/cosn_img.jpeg") 确保路径正确
  file_path = File.expand_path("tmp/cosn_img.jpeg")
  response = s3_client.put_object(
    body: File.open(file_path, "rb"), # 以二进制只读模式打开文件传入IO
    acl: "public-read",
    bucket: bucket_name,
    key: object_key,
    content_type: "image/jpeg" # 明确指定图片类型
  )
  !!response.etag
rescue StandardError => e
  puts "Error uploading object: #{e.message}"
  false
end

如果是大文件上传,更推荐用块形式打开文件避免资源泄漏:

File.open(file_path, "rb") do |file|
  response = s3_client.put_object(
    body: file,
    # 其余参数保持不变
  )
end

方案2:使用更简便的 upload_file 方法

AWS SDK 已经封装了专门用于本地文件上传的upload_file方法,直接传入文件路径即可,无需手动处理IO逻辑,适配大文件自动分片上传,更省心:

def object_uploaded?(bucket_name, object_key)
  s3_object = Aws::S3::Object.new(bucket_name, object_key, region: 'us-west-2')
  # 直接传入本地文件路径即可
  s3_object.upload_file("tmp/cosn_img.jpeg", acl: "public-read", content_type: "image/jpeg")
rescue StandardError => e
  puts "Error uploading object: #{e.message}"
  false
end

注意事项

  • 请确认本地文件路径的正确性,相对路径是相对于你执行Ruby脚本的工作目录,建议用File.expand_path或者框架提供的根路径方法(如Rails的Rails.root)生成绝对路径避免找不到文件的问题。
  • 如果上传的图片格式不固定,可以通过mime-types等Gem自动获取文件的MIME类型填入content_type参数。

内容的提问来源于stack exchange,提问作者McKay Whiting

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 16:54:03