web-dev-qa-db-ja.com

Amazon S3変更ファイルのダウンロード名

キー名としてGUIDを使用してS3にファイルを保存しています。

S3 REST API に従って、事前に署名されたURLを使用してダウンロードしています

元のファイル名を自分のデータベースに保存します。ユーザーがWebアプリケーションからファイルをクリックしてダウンロードするとき、元のファイル名を返したいのですが、現在取得できるのはGUIDだけです。どうすればこれを達成できますか?

私のWebアプリはsalesforceにあるので、response.redirectsですべてのファイルをWebサーバーにダウンロードし、ガバナーの制限によりファイル名を変更することはあまりできません。

使用できるHTMLリダイレクト、メタリフレッシュ、Javascriptがありますか? S3のダウンロードファイル名を変更する方法はありますか(考えられる唯一のことは、オブジェクトを新しい名前にコピーし、ダウンロードしてから削除することです)。

多くのユーザーが存在し、各バケット内の各ファイルに一意の名前があることを保証しないため、ユーザーごとにバケットを作成することは避けたい

他のソリューションはありますか?

75
Daveo

あなたのクロスがこの質問を Amazon S3フォーラム に投稿したと思いますが、他の人のためにここに答えを投稿したいと思います:

各S3オブジェクトに「ユーザーファイル名」が1つしかない場合、s3ファイルにContent-Dispositionヘッダーを設定して、ダウンロードファイル名を設定できます。Content-Disposition:attachment; filename = foo.bar

公平を期すために、Amazonフォーラムで正しい答えを提供するのは私ではなく、すべてのクレジットはColin Rhodesに送られるべきであることに言及したいと思います;-)

69
cloudberryman

受け入れられた答えは正しいですが、私はそれが非常に抽象的であり、利用するのが難しいと思います。

上記の問題を解決する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...]

}

s3.getSignedUrl関数に渡されるResponseContentDispositionオブジェクトのparams属性に注意してください。

http://docs.aws.Amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property のgetObject関数ドキュメントの詳細情報

24
Pawel

2011年1月上旬、S3はリクエストヘッダーのオーバーライドを追加しました。この機能により、個々のリクエストのContent-Dispositionヘッダーを「動的に」変更できます。

詳細については、S3 オブジェクトの取得に関するドキュメント を参照してください。

23
Uriah Carpenter

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);
1
Abhishek Basak

AWSSDKを使用するC#では、

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

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

var url = s3Client.GetPreSignedURL(request);
0
hkutluay

:response_content_dispositionがpresigned_urlメソッドに文書化されていないようです。これは私のために働いたものです

    signer = Aws::S3::Presigner.new
    signer.presigned_url(:get_object, bucket: @bucket, key: filename, 
    response_content_disposition: "attachment; filename =#{new_name}")
0
Chris Mcdonald

私は同じ問題を抱えています。S3にファイルを送信するときにhttpヘッダー「content-disposition」を設定することで解決しました。SDKバージョンはAWS SDK for PHP 3.xです。こちらはドキュメントです。 http://docs.amazonaws.cn/en_us/aws-sdk-php/latest/api-s3-2006-03-01.html#putobject

私のコードの一部

    public function __construct($config) 
    {
        $this->handle = new S3Client([
            'credentials' => array(
                'key' => $config['key'],
                'secret' => $config['secret'],
            ),
            ...
        ]);

        ...
    }

    public function putObject($bucket, $object_name, $source_file, $content_type = false, $acl = 'public-read', $filename = '')
    {
        try {
            $params = [
                'Bucket'      => $bucket,
                'Key'         => $object_name,
                'SourceFile'  => $source_file,
                'ACL'         => $acl,
            ];

            if ($content_type) $params['ContentType'] = $content_type;
            if ($filename) $params['ContentDisposition'] = 'attachment; filename="' . $filename . '"';

            $result = $this->handle->putObject($params);

            ...
        }
        catch(Exception $e)
        {
            ...
        }
    }
0
mok