Ruby on rails 未找到Amazon S3 copy_对象密钥-编码问题?
我将文件从JS前端上传到AmazonS3。使用aws-sdk-S3forRuby,我尝试将对象移动到另一个bucket。我正在为此使用Ruby on rails 未找到Amazon S3 copy_对象密钥-编码问题?,ruby-on-rails,ruby,amazon-web-services,amazon-s3,Ruby On Rails,Ruby,Amazon Web Services,Amazon S3,我将文件从JS前端上传到AmazonS3。使用aws-sdk-S3forRuby,我尝试将对象移动到另一个bucket。我正在为此使用Aws::S3::Client#copy_对象 出于测试目的,我上传了一个名为{}?^的文件#*äÄÜ?=)(;:-&%$§%2!|.jpg。当所有操作都适用于没有特殊字符的文件时,移动此文件会导致Aws::S3::Errors::InvalidArgument异常:不支持的复制源参数错误 我验证了该文件在我的S3存储桶中以该名称存在。以各种方式(CGI.esca
Aws::S3::Client#copy_对象
出于测试目的,我上传了一个名为{}?^的文件#*äÄÜ?=)(;:-&%$§%2!|.jpg
。当所有操作都适用于没有特殊字符的文件时,移动此文件会导致Aws::S3::Errors::InvalidArgument异常:不支持的复制源参数
错误
我验证了该文件在我的S3存储桶中以该名称存在。以各种方式(CGI.escape、URI.escape、URI.encode)编码对象密钥没有帮助
该代码段如下所示:
s3 = Aws::S3::Client.new(region: ENV['AWS_REGION'])
source_key = "{}?^°!#*äÄÜ?=)(;:- &%$§%2! |<>.jpg"
s3.copy_object({ copy_source: 'mybucket1/' + source_key,
bucket: 'mybucket2',
key: 'new_file_name.jpg' })
s3=Aws::s3::Client.new(region:ENV['Aws_region'])
source_key=“{}?^°!#*ÄÜ?=)(;:-&%$§%2!|.jpg”
s3.copy_对象({copy_source:'mybucket1/'+source_key,
桶:“我的桶2”,
键:“新文件名.jpg'})
有人知道为什么找不到复制源吗?密钥是否包含禁止使用的字符,或者我是否必须对它们进行不同的编码?我建议您在发送到S3之前替换所有特殊字符
source_key = "{}?^°!#*äÄÜ?=)(;:- &%$§%2! |<>"
source_key = I18n.transliterate(source_key)
source_key.gsub! /\W/, '_'
source_key += '.jpg'
source_key=“{}?^°!#*ÄÜ?=)(;:-&%$§%2!|”
source\u key=I18n.音译(source\u key)
source_key.gsub!/\W/,“\u”
source_key+='.jpg'
第一行是不带文件扩展名(
.jpg
)的源密钥名。第二行将任何特殊字符转换为最接近的字符,不带重音(a->a,e->e等)。第三行将转换为“u”不在[a-zA-Z]中的任何字符范围。最后一行添加了文件扩展名。音译没有奏效。我最终自己找到了答案:
有两个问题:对于表单提交,文件名被编码,所以像?
、%
和+
这样的特殊字符被转义。我必须对键执行URI.decode
,然后使用Aws::Sigv4::Signer.URI\u转义(字符串)对其重新编码aws sdk ruby的
。Amazon的编码方式不同,这就是造成混乱的原因。请查看uri\u escape的源代码
:
def uri_escape(string)
CGI.escape(string.encode('UTF-8')).gsub('+', '%20').gsub('%7E', '~')
end
我必须同意一件事。这是我见过的s3对象最奇怪的名称:-D。错误并不是说找不到源对象。它说参数“无效”和“不受支持”。您是否用简单的(即仅字母数字ASCII)验证了错误响应是什么不存在的源对象密钥?哦,你是对的。NoSuchKey是不存在的密钥的错误。