我使用带有预签名URL的AWS S3进行上传(putObject
(和下载(getObject
(。
我注意到生成的加载pdf的url是下载的,而不是显示在_blank
目标中。我跟踪到我的s3对象的元数据字段ContentType
设置为application/x-www-form-urlencoded
,而不是我请求的application/pdf
。当我在S3上手动更改内容类型元数据时,它就起作用了。
用于生成预签名的putObject
url的代码如下:
console.log("presigning with ", fileInput);
/* Will print something like:
presigning with [Object: null prototype] {
name: 'myFile.pdf',
mimetype: 'application/pdf',
size: 321528
}
*/
const { name, size, mimetype } = fileInput
const signedUrlExpireSeconds = 60 * 60
let data = {}
const key = "articles/" + Date.now().toString() + ".pdf"
let params = {
Bucket: 'mybucket',
Key: key,
Expires: signedUrlExpireSeconds,
ContentType: mimetype
};
data.url = await uploadToS3(params)// what I will use to upload from the client browser
export const uploadToS3 = (params) => {
AWS.config.update({
accessKeyId: process.env.S3ACCESSKEYID,
secretAccessKey: process.env.S3SECRETACCESSKEY,
region: process.env.S3REGION
});
var s3 = new AWS.S3();
return s3.getSignedUrlPromise('putObject', params);
}
生成的url确实包含如下内容类型选项(截断的url(:
https://mybucket.s3.eu-west-3.amazonaws.com/articles/1582299553999.pdf?Content-Type=application%2Fpdf&X-Amz-Algorithm......
但是,当我尝试在_blank
选项卡中显示pdf时,浏览器会下载它,因为在S3上传过程中设置了错误的application/x-www-form-urlencoded
内容类型。
我认为getObject
预签名的url是可以的,因为当我在S3上手动更新文件的内容类型时,它可以工作。
上传时我是不是遗漏了什么?
更新
我想知道这是否与基于预先签名的url提出的axios put请求有关。根据这个问题的评论,我设法获得了合适的内容类型。
然而,pdf无法加载,因为收藏夹不可用。。。有两个网络调用,一个用于304可以接受的pdf,另一个用于在firefox上收到400坏请求的favicon,以及在chrome上被禁止的403。因此(看起来(,pdf文件被视为无效。
我让favico文件成为唯一的公共文件,但PDF仍然被视为无效。但是,它在下载时显示正确。
对于每个人的未来参考,在发送预签名的URL请求时,您需要在请求、axios
或任何http客户端中提供内容类型。否则,它将被赋予这个application/x-www-form-urlencoded
。这就是为什么当使用.getObject
检索时,会看到Content-Type
设置为application/x-www-form-urlencoded
。