AWS S3:使用'response-content-disposition'强制文件下载

7
以下几行代码生成了一个签名URL,浏览器将通过该URL下载来自S3的文件。
我遇到了Chrome无法下载Octet Stream格式的PDF文件的众所周知问题。
解决方法是强制Chrome下载文件而不是尝试读取/打开它。
我尝试将'response-content-disposition'添加到签名和URL中,但没有起作用。
如何在生成URL时使用'response-content-disposition'头?
    String codedFilename=  EncodingUtil.urlEncode(bucketPath,'UTF-8');

    String stringtosign = 'GET\n\n\n'+Lexpires+'\n/'+bucketName+'/'+codedFilename;

    String signed = make_sig(stringtosign); 

    String codedsigned = EncodingUtil.urlEncode(signed,'UTF-8');

    String url = serverURL+'/'+bucketName+'/'+codedFilename+'?AWSAccessKeyId='+awskey+'&Expires='+Lexpires+'&Signature='+codedsigned;

注意:这是salesforce-apex语法。

自定义标头设置在文件本身上。当文件被下载时,这些标头将发送到客户端。我认为只有在文件首次上传时才能这样做。 - datasage
@datasage,S3文档没有为PUT请求指定“response-content-type”标签。因此,我认为我们无法在上传时设置该标头。(不过我可能是错的) - Ganesh Bhosle
3个回答

6
    String codedFilename=  EncodingUtil.urlEncode(bucketPath,'UTF-8');

    String stringtosign = 'GET\n\n\n'+Lexpires+'\n/'+bucketName+'/'+codedFilename+'?response-content-disposition=attachment; filename=abc.doc';

    String signed = make_sig(stringtosign); 

    String codedsigned = EncodingUtil.urlEncode(signed,'UTF-8');

    String url = serverURL+'/'+bucketName+'/'+codedFilename+'?response-content-disposition='+EncodingUtil.urlEncode('attachment; filename=abc.doc','UTF-8')+'&AWSAccessKeyId='+awskey+'&Expires='+Lexpires+'&Signature='+codedsigned;

来源:无法在S3覆盖内容配置头

如果文件类型是文档(例如PDF),而内容类型为'application/octet-stream',那么Chrome就存在问题。然而,如果内容类型是'binary/octet-stream',则Chrome就没有问题。

值得庆幸的是,如果在上传时没有设置任何内容,则S3将默认将下载的内容类型设置为'binary/Octet-stream'。

我的建议: 如果需要将“任何”类型的文件上传到S3,但在上传时不知道内容类型,请不要设置它或将其设置为“binary/Octet-stream”。这样,Chrome将显示警告,但仍能下载文件。


0

我创建了一个通过CloudFront函数实现此功能的解决方案,这是一种相对较新的做法(截至2022年8月)。我在这里记录了我的函数以及如何设置我的“S3存储桶位于CloudFront分发后面”:https://stackoverflow.com/a/73451456/19823883


你的回答可以通过提供额外的支持信息来得到改进。请[编辑]以添加更多详细信息,例如引用或文档,以便他人可以确认您的答案是正确的。您可以在帮助中心找到有关如何编写好答案的更多信息。 - Community

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接