【问题标题】:S3 URL encoding when generating Signed URL生成签名 URL 时的 S3 URL 编码
【发布时间】:2015-12-15 23:08:27
【问题描述】:

我有一个系统,在将文件上传到 S3 后,Lambda 作业会引发队列消息,我使用它来维护 MySQL 表中的键列表。

我正在尝试根据我的表中的记录生成一个预签名的 URL。

我目前有两条记录

/41jQnjTkg/thumbnail.jpg
/41jQnjTkg/Artist+-+Song.mp3

使用生成预签名 URL:

var params = {
        Bucket: bucket,
        Expires: Settings.UrlGetTimeout,
        Key: record
    };
S3.getSignedUrl('getObject', params);

带有thumbnail.jpg 的URL 可以正常工作,但是带有+-+ 的URL 却失败了。本地磁盘上的原始文件名为“Artist - Song.mp3”。 S3 将空格替换为“+”。现在,当我使用 S3 使用的完全相同的文件名生成 URL 时,它不起作用;我从 S3 收到“指定的密钥不存在”错误。

我必须怎么做才能为所有文件名一致地生成 URL?

【问题讨论】:

    标签: amazon-web-services amazon-s3


    【解决方案1】:

    经过一些实验,我解决了这个问题。

    我不是直接存储 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/event 消息不一致。

    如果我直接使用 S3 本身在 SQS 事件消息中提供的密钥生成签名 URL,它就不会起作用。必须对密钥执行此字符串替换步骤和 URL 解码,以便使用它来获得正确的工作 url。

    不确定这是设计使然还是错误。

    【讨论】:

    • 遇到了同样的问题。当从 S3 事件获得 SQS 通知时,s3 对象名称已编码,但签名 url 想要对其进行解码。
    【解决方案2】:

    第二个文件的名称是form-urlencoded+ 实际上是一个空格,如果您有其他字符(如括号),它们将被百分比转义。在进一步处理数据之前,您需要通过 URL 解码器运行数据。

    旁注:如果您的 Lambda 函数所做的唯一事情是创建 SQS 消息,您可以直接从 S3 执行此操作,而无需编写自己的函数。

    【讨论】:

    • 是的,我应该更正我的问题。我使用 S3 事件生成了一条 SQS 消息,我在我的应用程序中捕获并处理该消息。
    猜你喜欢
    • 2019-03-11
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 2015-09-05
    • 2018-12-06
    • 2020-06-06
    • 2021-07-25
    • 1970-01-01
    相关资源
    最近更新 更多