J'ai des fichiers stockés sur S3 avec un GUID comme nom de clé.
J'utilise une URL pré-signée pour télécharger selon S3 REST API
Je stocke le nom du fichier d'origine dans ma propre base de données. Lorsqu'un utilisateur clique pour télécharger un fichier à partir de mon application Web , je veux retourner son nom de fichier d'origine, mais actuellement tout ce qu'il obtient est un GUID . Comment puis-je atteindre cet objectif?
Mon application Web est dans Salesforce, je n'ai donc pas beaucoup de contrôle pour faire une réponse. Redirige tous les fichiers vers le serveur Web, puis renommez-le en raison des limitations du gouverneur.
Y a-t-il une redirection HTML, une méta-actualisation, Javascript que je peux utiliser? Existe-t-il un moyen de changer le nom du fichier de téléchargement pour S3 (la seule chose à laquelle je peux penser est de copier l'objet vers un nouveau nom, de le télécharger, puis de le supprimer).
Je veux éviter de créer un compartiment par utilisateur car nous aurons beaucoup d'utilisateurs et toujours aucune garantie que chaque fichier avec dans chaque compartiment aura un nom unique
D'autres solutions?
Je suppose que votre croix a posté ces questions sur forum Amazon S , mais pour le bien des autres, j'aimerais poster la réponse ici:
S'il n'y a qu'un seul "nom de fichier utilisateur" pour chaque objet S3, vous pouvez définir l'en-tête Content-Disposition sur votre fichier s3 pour définir le nom de fichier à télécharger: Content-Disposition: attachment; filename = foo.bar
Par souci d'équité, je voudrais mentionner que ce n'était pas moi de fournir la bonne réponse sur le forum Amazon et tous les crédits devraient aller à Colin Rhodes ;-)
Bien que la réponse acceptée soit correcte, je la trouve très abstraite et difficile à utiliser.
Voici un morceau de code node.js qui résout le problème indiqué. Je conseille de l'exécuter en tant qu'AWS Lambda pour générer une URL pré-signée.
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...]
}
Veuillez prendre note de l'attribut ResponseContentDisposition
de l'objet params
passé dans s3.getSignedUrl
une fonction.
Plus d'informations sous la fonction getObject doc à http://docs.aws.Amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getObject-property
Début janvier 2011, S3 a ajouté des remplacements d'en-tête de demande. Cette fonctionnalité vous permet de modifier "dynamiquement" l'en-tête Content-Disposition pour les demandes individuelles.
Voir le S3 documentation sur l'obtention d'objets pour plus de détails.
Pour Java AWS SDK ci-dessous, l'extrait de code devrait faire le travail:
GeneratePresignedUrlRequest generatePresignedUrlRequest =
new GeneratePresignedUrlRequest(s3Bucket, objectKey)
.withMethod(HttpMethod.GET)
.withExpiration(getExpiration());
ResponseHeaderOverrides responseHeaders = new ResponseHeaderOverrides();
responseHeaders.setContentDisposition("attachment; filename =\"" + fileName + "\"");
generatePresignedUrlRequest.setResponseHeaders(responseHeaders);
Avec C # utilisant 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);
Il ressemble à ceci: response_content_disposition n'est pas documenté dans la méthode presigned_url. C'est ce qui a fonctionné pour moi
signer = Aws::S3::Presigner.new
signer.presigned_url(:get_object, bucket: @bucket, key: filename,
response_content_disposition: "attachment; filename =#{new_name}")
J'ai le même problème, je l'ai résolu en définissant l'en-tête http "content-disposition" tout en soumettant le fichier à S3, la version du SDK est AWS SDK pour PHP 3.x. voici la doc http://docs.amazonaws.cn/en_us/aws-sdk-php/latest/api-s3-2006-03-01.html#putobject
un morceau de mon code
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)
{
...
}
}