Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 未找到Amazon S3 copy_对象密钥-编码问题?_Ruby On Rails_Ruby_Amazon Web Services_Amazon S3 - Fatal编程技术网

Ruby on rails 未找到Amazon S3 copy_对象密钥-编码问题?

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

我将文件从JS前端上传到AmazonS3。使用aws-sdk-S3forRuby,我尝试将对象移动到另一个bucket。我正在为此使用
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是不存在的密钥的错误。