Amazon S3更改文件下载名称

Dav*_*veo 79 rest amazon-s3 amazon-web-services

我有文件存储在S3上,GUID作为键名.

我正在使用预签名的URL按照S3 REST API下载

我将原始文件名存储在我自己的数据库中.当用户单击从我的Web应用程序下载文件时,我想返回其原始文件名,但目前他们得到的只是一个GUID.我怎样才能做到这一点?

我的网络应用程序在salesforce中,所以我没有太多控制权来做响应.所有人都将文件下载到网络服务器,然后由于州长限制重命名.

是否有一些HTML重定向,元刷新,我可以使用Javascript?有没有办法改变S3的下载文件名(我唯一能想到的是将对象复制到新名称,下载,然后删除它).

我想避免为每个用户创建一个存储桶,因为我们会有很多用户,但仍然不能保证每个存储桶中的每个文件都有一个唯一的名称

还有其他方法吗?

小智 72

我想你的十字架已经将这些问题发布到了亚马逊S3论坛,但是为了别人的缘故,我想在这里发布答案:

如果每个S3对象只有一个"用户文件名",则可以在s3文件上设置Content-Disposition标头以设置下载文件名:Content-Disposition:attachment; 文件名= foo.bar

为了公平起见,我想提一下,不是我在亚马逊论坛上提供正确答案而且所有学分应该归科林罗德;-)

  • @alaster 这对你有用吗?我收到“我们计算的请求签名与您提供的签名不匹配”。检查您的密钥和签名方法。` 当我删除此 `response-content-disposition=attachment;filename=foo.bar` 时,它会下载文件,但使用原始名称。 (3认同)
  • 请看下面的答案,自2011年1月起,也可以按照GET请求进行.因此,可以根据需要拥有尽可能多的"用户文件名". (2认同)
  • 我需要在文件名中添加引号才能使其正常工作,所以我的标题是:Content-Disposition:attachment; 文件名= "foo.bar" (2认同)
  • 您可以动态覆盖响应标头:`https://...example.txt?response-content-disposition=attachment;filename=foo.bar` (2认同)

Paw*_*wel 27

虽然接受的答案是正确的,但我发现它非常抽象,难以利用.

这是一段解决所述问题的node.js代码.我建议将其作为AWS Lambda执行以生成预先签名的Url.

var AWS = require('aws-sdk');
var s3 = new AWS.S3({
    signatureVersion: 'v4'
});
const s3Url = process.env.BUCKET;

module.exports.main = (event, context, callback) => {
var s3key = event.s3key
var originalFilename = event.originalFilename

var url = s3.getSignedUrl('getObject', {
        Bucket: s3Url,
        Key: s3key,
        Expires: 600,
        ResponseContentDisposition: 'attachment; filename ="' + originalFilename + '"'
    });

[... rest of Lambda stuff...]

}
Run Code Online (Sandbox Code Playgroud)

请注意传递给函数ResponseContentDispositionparams对象的属性s3.getSignedUrl.

有关getObject function doc下的更多信息,请访问http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property


Uri*_*ter 23

在2011年1月初,S3添加了请求标头覆盖.此功能允许您"动态"更改单个请求的Content-Disposition标头.

有关详细信息,请参阅有关获取对象的S3 文档.


hku*_*uay 6

使用 C# 使用 AWSSDK,

GetPreSignedUrlRequest request = new GetPreSignedUrlRequest
{
    BucketName = BucketName,
    Key = Key,
    Expires = DateTime.Now.AddMinutes(25) 
};

request.ResponseHeaderOverrides.ContentDisposition = $"attachment; filename={FileName}";

var url = s3Client.GetPreSignedURL(request);
Run Code Online (Sandbox Code Playgroud)


小智 5

对于 Java AWS SDK,下面的代码片段应该可以完成这项工作:

GeneratePresignedUrlRequest generatePresignedUrlRequest = 
                new GeneratePresignedUrlRequest(s3Bucket, objectKey)
                .withMethod(HttpMethod.GET)
                .withExpiration(getExpiration());

ResponseHeaderOverrides responseHeaders = new ResponseHeaderOverrides();
responseHeaders.setContentDisposition("attachment; filename =\"" + fileName + "\"");

generatePresignedUrlRequest.setResponseHeaders(responseHeaders);
Run Code Online (Sandbox Code Playgroud)