Подтвердить что ты не робот

Amazon S3

У меня есть файлы, хранящиеся на S3 с идентификатором GUID в качестве имени ключа.

Я использую предварительно подписанный URL для загрузки по S3 REST API

Я сохраняю исходное имя файла в своей собственной базе данных. Когда пользователь нажимает, чтобы загрузить файл из моего веб-приложения , я хочу вернуть исходное имя файла, но в настоящее время все, что они получают, это GUID. Как я могу достичь этого?

Мое веб-приложение работает в salesforce, поэтому у меня нет большого контроля за выполнением response.redirects, все файлы загружаются на веб-сервер, а затем переименовывают его из-за ограничений, присущих губернатору.

Есть ли какая-либо переадресация HTML, мета-обновление, Javascript, который я могу использовать? Есть ли способ изменить имя файла загрузки для S3 (единственное, о чем я могу думать, - это совместить объект с новым именем, загрузить его, а затем удалить его).

Я хочу, чтобы не создавать bucket для каждого пользователя, поскольку у нас будет много пользователей, и все равно нет гарантии, что каждый файл в каждом ведре будет иметь уникальное имя

Любые другие решения?

4b9b3361

Ответ 1

Я думаю, ваш крест разместил эти вопросы на форуме Amazon S3, но ради других я хотел бы разместить здесь ответ:

Если для каждого объекта S3 существует только одно "имя пользователя", то вы можете установить заголовок Content-Disposition в файле s3, чтобы установить имя файла загрузки: Content-Disposition: вложение; имя файла = foo.bar

Ради справедливости я хотел бы упомянуть, что я не мог дать правильный ответ на форуме Amazon, и все кредиты должны отправиться в Колин Родос; -)

Ответ 2

Хотя принятый ответ является правильным, я нахожу его очень абстрактным и трудным для использования.

Вот фрагмент кода 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...]

}

Обратите внимание на атрибут ResponseContentDisposition объекта params переданный в функцию s3.getSignedUrl.

Дополнительную информацию см. В разделе "Функция-документ getObject" по адресу http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property.

Ответ 3

В начале января 2011 года S3 добавил заголовок заголовка запроса. Эта функциональность позволяет вам "динамически" изменять заголовок Content-Disposition для отдельных запросов.

Подробнее см. документацию S3 для получения объектов.

Ответ 4

Это выглядит так: 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}")

Ответ 5

Для Java AWS SDK ниже Code Snippet должен выполнить эту работу:

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

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

generatePresignedUrlRequest.setResponseHeaders(responseHeaders);

Ответ 6

У меня та же проблема, я решил ее, установив http-заголовок "content-disposition", пока отправляю файл на S3, версия SDK - AWS SDK для 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)
        {
            ...
        }
    }

Ответ 7

С С# с использованием 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);