Mengunggah Gambar berenkode base64 ke Amazon S3 melalui Node.js

103

Kemarin saya melakukan sesi pengkodean malam yang dalam dan membuat node.js / JS kecil (sebenarnya CoffeeScript, tapi CoffeeScript hanya JavaScript jadi katakanlah JS) aplikasi.

apa tujuannya:

  1. klien mengirim kanvas datauri (png) ke server (melalui socket.io)
  2. server mengunggah gambar ke amazon s3

langkah 1 selesai.

server sekarang memiliki string a la

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

pertanyaan saya adalah: apa langkah saya selanjutnya untuk "mengalirkan" / mengunggah data ini ke Amazon S3 dan membuat gambar yang sebenarnya di sana?

knox https://github.com/LearnBoost/knox tampak seperti lib yang luar biasa untuk PUT sesuatu ke S3, tetapi yang saya lewatkan adalah perekat antara string gambar yang dikodekan base64 dan tindakan pengunggahan yang sebenarnya ?

Semua ide, petunjuk, dan umpan balik diterima.

Franz Enzenhofer
sumber
4
Periksa jawaban ini: stackoverflow.com/questions/5867534/…
akirk

Jawaban:

218

Untuk orang yang masih bergumul dengan masalah ini. Berikut adalah pendekatan yang saya gunakan dengan native aws-sdk:

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

Di dalam metode router Anda (ContentType harus disetel ke jenis konten file gambar):

  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!');
      }
  });

s3_config.json file:

{
  "accessKeyId":"xxxxxxxxxxxxxxxx",
  "secretAccessKey":"xxxxxxxxxxxxxx",
  "region":"us-east-1"
}
Divyanshu Das
sumber
2
[MissingRequiredParameter: 'Key' yang diperlukan tidak ada di params]
Nichole A. Miler
1
Kunci: req.body.userId Saya menggunakan userId sebagai kunci dalam data posting ... sudah lama kembali ... tetapi Anda dapat mendeklarasikan string apa pun sebagai kunci. Untuk memastikan file yang sudah ada tidak ditimpa, pertahankan agar kunci tetap unik.
Divyanshu Das
@Divyanshu Terima kasih atas contoh yang bermanfaat. Saya mendapat dua keraguan: How to make S3 generates a unique KEY to prevent from overriding files?dan If I don't set the ContentType, when I download the files I won't be able to get the correct file?maksud saya, saya akan mendapatkan file yang rusak seperti itu? Terima kasih sebelumnya!
alexventuraio
2
Jalur lokasi @ Marklar pada dasarnya adalah kunci - misalnya jika nama bucket Anda adalah - bucketone dan nama kuncinya adalah xyz.png, maka jalur file akan menjadi bucketone.s3.amazonaws.com/xyz.png
Divyanshu Das
2
@Divyanshu Terima kasih atas jawaban yang bagus ini! Itu sangat membantu saya. Namun, menurut saya ContentEncoding: 'base64'tidak benar karena new Buffer(..., 'base64')mendekode string yang dikodekan base64 menjadi representasi binernya.
Shuhei Kagawa
17

ok, ini adalah jawaban bagaimana cara menyimpan data kanvas ke file

pada dasarnya itu longgar seperti ini di kode saya

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)
Franz Enzenhofer
sumber
1
Objek buffer akan menampilkan error "Buffer not define" dapatkah Anda memberi saya solusi untuk itu.
NaveenG
Saya juga mendapatkan kesalahan yang sama. Anda mendapat solusi atau tidak
Krishna
1
@NaveenG Ini adalah contoh node, mungkin Anda menggunakan JS biasa?
Pointi
9

Berikut kode dari satu artikel yang saya temukan, posting di bawah ini:

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;

Baca selengkapnya: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property

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

Harvey
sumber
4

Jawaban yang diterima berfungsi dengan baik tetapi jika seseorang perlu menerima file apa pun, bukan hanya gambar, regexp ini berfungsi dengan baik:

/^data:.+;base64,/

Ms01
sumber