Amazon S3 Изменить имя загрузки файла - PullRequest
67 голосов
/ 10 апреля 2010

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

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

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

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

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

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

Есть ли другие решения?

Ответы [ 4 ]

66 голосов
/ 10 апреля 2010

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

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

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

21 голосов
/ 27 января 2011

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

См. Документацию S3 о получении объектов для получения более подробной информации.

20 голосов
/ 21 ноября 2017

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

Вот фрагмент кода node.js, который решает указанную проблему.Я советую использовать его как лямбда-AWS для генерации предварительно подписанного 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 function doc на http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property

0 голосов
/ 20 июня 2019

У меня та же проблема, я решил ее, установив 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)
        {
            ...
        }
    }
...