143 votes

Téléchargement d'une image encodée en base64 vers Amazon S3 via Node.js

Hier, j'ai fait une séance de codage nocturne et j'ai créé une petite application node.js/JS (en fait CoffeeScript, mais CoffeeScript est juste du JavaScript, alors disons JS).

quel est l'objectif :

  1. le client envoie un canvas datauri (png) au serveur (via socket.io)
  2. le serveur télécharge l'image sur amazon s3

l'étape 1 est terminée.

le serveur a maintenant une chaîne de caractères à la

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACt...

ma question est la suivante : Quelles sont les étapes suivantes pour "streamer"/uploader ces données sur Amazon S3 et y créer une image réelle ?

renard https://github.com/LearnBoost/knox semble être une librairie géniale pour mettre quelque chose sur S3, mais il me manque le lien entre la chaîne d'image encodée en base64 et l'action de téléchargement proprement dite. ?

Toutes les idées, les conseils et les commentaires sont les bienvenus.

298voto

Divyanshu Points 158

Pour les personnes qui sont encore aux prises avec ce problème. Voici l'approche que j'ai utilisée avec le aws-sdk natif :

var AWS = require('aws-sdk');
AWS.config.loadFromPath('./s3_config.json');
var s3Bucket = new AWS.S3( { params: {Bucket: 'myBucket'} } );

À l'intérieur de votre méthode de routeur ( ContentType doit correspondre au type de contenu du fichier image) :

  var buf = Buffer.from(req.body.imageBinary.replace(/^data:image\/\w+;base64,/, ""),'base64')
  var data = {
    Key: req.body.userId, 
    Body: buf,
    ContentEncoding: 'base64',
    ContentType: 'image/jpeg'
  };
  s3Bucket.putObject(data, function(err, data){
      if (err) { 
        console.log(err);
        console.log('Error uploading data: ', data); 
      } else {
        console.log('successfully uploaded the image!');
      }
  });

Fichier s3_config.json :

{
  "accessKeyId":"xxxxxxxxxxxxxxxx",
  "secretAccessKey":"xxxxxxxxxxxxxx",
  "region":"us-east-1"
}

24voto

Harshal Points 2993

Voici le code d'un article que j'ai trouvé, posté ci-dessous :

const imageUpload = async (base64) => {

  const AWS = require('aws-sdk');

  const { ACCESS_KEY_ID, SECRET_ACCESS_KEY, AWS_REGION, S3_BUCKET } = process.env;

  AWS.config.setPromisesDependency(require('bluebird'));
  AWS.config.update({ accessKeyId: ACCESS_KEY_ID, secretAccessKey: SECRET_ACCESS_KEY, region: AWS_REGION });

  const s3 = new AWS.S3();

  const base64Data = new Buffer.from(base64.replace(/^data:image\/\w+;base64,/, ""), 'base64');

  const type = base64.split(';')[0].split('/')[1];

  const userId = 1;

  const params = {
    Bucket: S3_BUCKET,
    Key: `${userId}.${type}`, // type is not required
    Body: base64Data,
    ACL: 'public-read',
    ContentEncoding: 'base64', // required
    ContentType: `image/${type}` // required. Notice the back ticks
  }

  let location = '';
  let key = '';
  try {
    const { Location, Key } = await s3.upload(params).promise();
    location = Location;
    key = Key;
  } catch (error) {
  }

  console.log(location, key);

  return location;

}

module.exports = imageUpload;

Lire la suite : http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property

Crédits : https://medium.com/@mayneweb/upload-a-base64-image-data-from-nodejs-to-aws-s3-bucket-6c1bd945420f

19voto

Franz Enzenhofer Points 1703

Ok, celui-ci est la réponse comment enregistrer les données de la toile dans un fichier

En gros, cela se passe comme suit dans mon code

buf = new Buffer(data.dataurl.replace(/^data:image\/\w+;base64,/, ""),'base64')

req = knoxClient.put('/images/'+filename, {
             'Content-Length': buf.length,
             'Content-Type':'image/png'
  })

req.on('response', (res) ->
  if res.statusCode is 200
      console.log('saved to %s', req.url)
      socket.emit('upload success', imgurl: req.url)
  else
      console.log('error %d', req.statusCode)
  )

req.end(buf)

10voto

cubsink Points 735

La réponse acceptée fonctionne très bien, mais si quelqu'un a besoin d'accepter n'importe quel fichier au lieu de seulement des images, cette expression rationnelle fonctionne très bien :

/^data:.+;base64,/

0voto

ObiTech Invents Points 181

Pour les développeurs laravel, cela devrait fonctionner

/* upload the file  */
$path = Storage::putFileAs($uploadfolder, $uploadFile, $fileName, "s3");

assurez-vous de définir la propriété de votre fichier .env avant d'appeler cette méthode

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X