我有一个系统,在将文件上传到S3后,Lambda作业会引发一个队列消息,我用它来维护MySQL表中的键列表。
我正在尝试根据表格中的记录生成预签名的网址。
我目前有两条记录
/41jQnjTkg/thumbnail.jpg
/41jQnjTkg/Artist+-+Song.mp3
使用以下方式生成预签名网址:
var params = {
Bucket: bucket,
Expires: Settings.UrlGetTimeout,
Key: record
};
S3.getSignedUrl('getObject', params);
thumbnail.jpg
的网址完全正常,但+-+
的网址失败。本地磁盘上的原始文件名是“Artist - Song.mp3”。 S3用'+'替换空格。现在,当我使用S3使用的完全相同的文件名生成URL时,它不起作用;我从S3得到“指定密钥不存在”错误。
我必须为所有文件名一致地生成URL?
答案 0 :(得分:0)
第二个文件的名称即将发送给您form-urlencoded。 +
实际上是一个空格,如果你有其他字符(如括号),它们将被百分比转义。在进一步使用之前,您需要通过URL解码器运行数据。
旁注:如果您的Lambda函数唯一能做的就是创建一条SQS消息,您可以直接从S3执行此操作而无需编写自己的函数。
答案 1 :(得分:0)
我没有直接存储S3在S3事件消息中提供的密钥,而是首先用空格替换'+'字符(因为它们最初在磁盘上),然后对其进行URL解码。
return decodeURIComponent(str.replace(/\+/img, " "));
现在生成S3预签名URL可以按预期工作。
在MySQL拥有以下记录之前:
/41jQnjTkg/thumbnail.jpg
/41jQnjTkg/Artist+-+Song.mp3
现在:
/41jQnjTkg/thumbnail.jpg
/41jQnjTkg/Artist - Song.mp3
我个人觉得S3的api /事件消息不一致。
如果我直接使用S3本身在SQS事件消息中提供的密钥生成了签名URL,那就不会有效。必须做这个字符串替换步骤&对密钥进行URL解码,以便使用它来获取正确的工作URL。
不确定这是设计还是错误。