Base64 kodlu Görüntüyü Node.js aracılığıyla Amazon S3'e yükleme


103

Dün derin bir gece kodlama oturumu yaptım ve küçük bir node.js / JS oluşturdum (aslında CoffeeScript, ancak CoffeeScript sadece JavaScript, yani JS diyelim) uygulaması.

amaç nedir:

  1. istemci, sunucuya bir tuval verisi (png) gönderir (socket.io aracılığıyla)
  2. sunucu görüntüyü amazon s3'e yükler

1. adım tamamlandı.

sunucu artık bir la dizesine sahip

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

Sorum şu: Bu verileri Amazon S3'e "aktarmak" / yüklemek ve orada gerçek bir görüntü oluşturmak için sonraki adımlarım nedir?

knox https://github.com/LearnBoost/knox , S3'e bir şeyler PUT için harika bir kitap gibi görünüyor, ancak eksik olan şey, base64 kodlu görüntü dizesi ile gerçek yükleme eylemi arasındaki tutkal mı?

Herhangi bir fikir, işaret ve geri bildirim hoş geldiniz.


4
Bu yanıtı kontrol edin: stackoverflow.com/questions/5867534/…
akirk

Yanıtlar:


218

Hala bu sorunla mücadele eden insanlar için. Yerel aws-sdk ile kullandığım yaklaşım:

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

Yönlendirici yönteminizin içinde (ContentType, görüntü dosyasının içerik türüne ayarlanmalıdır):

  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 dosyası:

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

2
[MissingRequiredParameter: Parametrelerde gerekli anahtar "Anahtar" eksik]
Nichole A. Miler

1
Anahtar: req.body.userId userId'yi posta verilerinde anahtar olarak kullandım ... uzun zaman önce ... ancak herhangi bir dizeyi anahtar olarak bildirebilirsiniz. Mevcut dosyaların üzerine yazılmadığından emin olmak için anahtarı benzersiz tutun.
Divyanshu Das

@Divyanshu Böyle yararlı bir örnek için teşekkürler. İki şüphem var: How to make S3 generates a unique KEY to prevent from overriding files?ve If I don't set the ContentType, when I download the files I won't be able to get the correct file?demek istediğim, böyle bozuk bir dosya alacağım? Şimdiden teşekkürler!
alexventuraio

2
@Marklar konum yolu temelde anahtardır - örneğin, paket adınız - bucketone ve anahtar adınız xyz.png ise, dosya yolu bucketone
Divyanshu Das

2
@Divyanshu Bu harika cevap için teşekkürler! Bana çok yardımcı oldu. Ancak, base64 kodlu dizeyi ikili gösterimine dönüştürdüğü için ContentEncoding: 'base64'doğru olmadığını düşünüyorum new Buffer(..., 'base64').
Shuhei Kagawa

17

Tamam, bu, tuval verilerinin dosyaya nasıl kaydedileceğinin yanıtı

temelde benim kodumda böyle gevşek

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)

1
Buffer nesnesi "Buffer not define" hatası atacak, bunun için bana bir çözüm verebilir misiniz?
NaveenG

Ben de aynı hatayı alıyorum. herhangi bir çözümün var ya da yok
Krishna

1
@NaveenG Bu bir düğüm örneğidir, belki düz JS kullanıyorsunuz?
Pointi

9

Karşılaştığım bir makalenin kodu aşağıdadır:

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;

Daha fazlasını okuyun: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property

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


4

Kabul edilen yanıt harika çalışıyor, ancak birinin yalnızca resimler yerine herhangi bir dosyayı kabul etmesi gerekiyorsa, bu normal ifade harika çalışıyor:

/^data:.+;base64,/

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.