我使用java的aws-sdk将文件上传到s3(法兰克福地区)。
ObjectMetadata omd = new ObjectMetadata();
omd.setContentDisposition("attachment;filename=\"" + someFileNameWithNonASCIIChars + "\"");
...
PutObjectRequest por = new PutObjectRequest(bucket, key, stream, omd);
s3Object.putObject(por);
最后一行抛出 AmazonServiceException
,说明 SignatureDoesNotMatch 作为原因:
The request signature we calculated does not match the signature you provided.
只有当 Content-Disposition header 值中包含非 ASCII 字符时,才会发生这种情况。
我知道无法处理 utf-8 编码解码的浏览器的解决方法:
How to encode the filename parameter of Content-Disposition header in HTTP?
我可以使用这个解决方案。 但这是S3的预期结果吗? 有没有办法在 Content-Disposition header 中发送 UTF-8 字符?然后我就可以让浏览器处理非 ASCII 字符。
此外,使用 *=utf-8''
解决方法会导致空格被解码为“+”符号而不是返回空格,这并不理想。已解释here .
谢谢。
最佳答案
But is this the intended result from S3?
不幸的是,确实如此。 S3 的一个长期存在的问题是,当 header 包含非 ascii 字符时,实际上正确的签名无法被检测为正确,因为该服务实际上错误地计算了签名 - 显然原始设计假设 utf-8 字符应该不存在...所以不能使用 utf-8 值。
对于 +
问题,只需在编码后将其更改为 %20
即可。编码之前文件名中的任何实际 +
都将在编码字符串中显示为 %2B
,因此任何剩余的 +
实际上都是空格。
关于amazon-web-services - 具有非 ASCII Content-Disposition header 的 S3 PutObjectRequest 会引发异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49920559/