[rest] Amazon S3 파일 다운로드 이름 변경

키 이름으로 GUID를 사용하여 S3에 파일이 저장되어 있습니다.

사전 서명 된 URL을 사용하여 S3 REST API에 따라 다운로드하고 있습니다.

내 데이터베이스에 원래 파일 이름을 저장합니다. 사용자가 내 웹 응용 프로그램에서 파일을 다운로드하기 위해 클릭하면 원래 파일 이름을 반환하고 싶지만 현재 얻는 것은 GUID뿐입니다 . 어떻게하면 되나요?

내 웹 앱이 세일즈 포스에 있으므로 response.redirects를 수행 할 수있는 권한이 많지 않습니다. 모든 파일을 웹 서버로 다운로드 한 다음 관리자 제한으로 인해 이름을 바꿉니다.

HTML 리디렉션, 메타 새로 고침, Javascript를 사용할 수 있습니까? S3의 다운로드 파일 이름을 변경할 수있는 방법이 있습니까? (내가 생각할 수있는 유일한 방법은 객체를 새 이름으로 복사하고 다운로드 한 다음 삭제하는 것입니다).

사용자가 많지만 각 버킷에있는 각 파일이 고유 한 이름을 가질 것이라는 보장은 없으므로 사용자별로 버킷을 만드는 것을 피하고 싶습니다.

다른 해결책이 있습니까?



답변

나는 당신의 십자가가 Amazon S3 포럼 에이 질문을 게시했다고 생각 하지만 다른 사람들을 위해 여기에 답변을 게시하고 싶습니다.

각 S3 객체에 대해 하나의 “사용자 파일 이름”만있는 경우 s3 파일에 Content-Disposition 헤더를 설정하여 다운로드 파일 이름을 설정할 수 있습니다. Content-Disposition : attachment; filename = foo.bar

공정성을 위해 Amazon 포럼에서 정답을 제공하는 것은 제가 아니었고 모든 크레딧은 Colin Rhodes에 가야한다는 점을 언급하고 싶습니다 😉


답변

받아 들여지는 대답은 정확하지만 매우 추상적이며 활용하기가 어렵습니다.

여기에 언급 된 문제를 해결하는 node.js 코드가 있습니다. 미리 서명 된 Url을 생성하려면 AWS Lambda로 실행하는 것이 좋습니다.

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...]

}

함수에 전달 된 객체 의 ResponseContentDisposition속성을 참고하십시오 .paramss3.getSignedUrl

http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property의 getObject 함수 문서에 대한 자세한 정보


답변

2011 년 1 월 초 S3는 요청 헤더 재정의를 추가했습니다. 이 기능을 사용하면 개별 요청에 대한 Content-Disposition 헤더를 ‘동적으로’변경할 수 있습니다.

자세한 내용은 객체 가져 오기에 대한 S3 설명서 를 참조하십시오.


답변

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);


답변

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);


답변

동일한 문제가 있습니다. 파일을 S3에 제출하는 동안 http 헤더 “content-disposition”을 설정하여 해결했습니다. SDK 버전은 PHP 3.x 용 AWS SDK입니다. 여기 문서 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)
        {
            ...
        }
    }


답변

: 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}")