在响应内容处置中添加* = utf-8''

问题描述

目前,我签名的URL都如下所示,并且可以正常工作:

https://cloudfront/filekey?response-content-disposition=inline%3Bfilename%3D{utf-8-encoded-filename.pdf}&Expires=...

但是某些文件名包含Unicode字符,因此CloudFront将返回:

<Error>
    <Code>InvalidArgument</Code>
    <Message>
        Header value cannot be represented using ISO-8859-1.
    </Message>
    <ArgumentName>response-content-disposition</ArgumentName>
    <ArgumentValue>inline;filename=文件名 - abc.pdf</ArgumentValue>
    <RequestId>1234567890</RequestId>
    <HostId>
        123456789
    </HostId>
</Error>

因此,正如许多人所建议的(例如AWS Developer Forums),我在响应内容分配中添加了* = uft-8'',如下所示:

https://cloudfront/filekey?response-content-disposition=inline%3Bfilename%2A%3DUTF-8%27%27{utf-8-encoded-filename.pdf}&Expires=...

现在它返回

<Error>
  <Code>AccessDenied</Code>
  <Message>Access denied</Message>
</Error>

原始域名的格式为:AWSDOC-EXAMPLE-BUCKET.s3.eu-west-1.amazonaws.com,因此它是S3 REST API端点。

原始访问身份(OAI)已配置有现有身份。我选择手动更新S3存储桶上的权限。

在S3中,对象是AES-256加密的。在存储区策略中,只有一个语句允许OAI访问。此存储桶和对象的所有者是同一帐户。

阅读I’m using an S3 REST API endpoint as the origin of my CloudFront distribution. Why am I getting 403 Access Denied errors?之后,我开始认为可能是因为文件名不匹配?

上载的文件名为文件名-abc.pdf ,但在s3中显示为 _-_ abc.pdf 。但是我尝试在 response-content-disposition 中使用 _-_ abc.pdf ,它仍然使我无法访问。

解决方法

我终于使它工作了,所以我认为最好在这里写我的解决方案。

当对象上传到S3时,其文件名将被编码,正如我在问题中提到的:文件名-abc.pdf -> _-_ abc.pdf 。但是保存在我们数据库中的文件名仍然是原始文件名,因此,由于文件名错误,它将返回拒绝访问的信息。

但是,如果我在 response-content-disposition 中使用 _-__ abc.pdf ,它仍然会返回拒绝访问的信息。因为我忘记了我使用的是签名URL,并且它是基于对象密钥和 response-content-disposition 进行签名的。

所以在这里我根本不需要添加utf-8。而且,我应该修改自己的网址生成代码,而不是简单地在浏览器中更改 response-content-disposition

此外,由于我不确定S3如何编码文件名,因此我直接从对象键中提取文件名。下面是我用Scala编写的代码:

// r.s3ObjectKey is in format: YYYY/MM/DD/encodedFileName-digits
val fileName = r.s3ObjectKey.split("/").last.split("-").dropRight(1).mkString("-")

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...