Tải hình ảnh được mã hóa base64 lên Amazon S3 qua Node.js


99

Hôm qua, tôi đã thực hiện một phiên viết mã ban đêm sâu và tạo một ứng dụng node.js / JS nhỏ (thực ra là CoffeeScript, nhưng CoffeeScript chỉ là JavaScript, vì vậy hãy nói JS).

mục tiêu là gì:

  1. máy khách gửi một dữ liệu canvas (png) tới máy chủ (qua socket.io)
  2. máy chủ tải hình ảnh lên amazon s3

bước 1 đã xong.

máy chủ bây giờ có một chuỗi a la

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

câu hỏi của tôi là: các bước tiếp theo của tôi để "phát trực tuyến" / tải dữ liệu này lên Amazon S3 và tạo hình ảnh thực tế ở đó là gì?

knox https://github.com/LearnBoost/knox có vẻ như là một lib tuyệt vời để PUT thứ gì đó lên S3, nhưng điều tôi còn thiếu là chất kết dính giữa base64-encoded-image-string và hành động tải lên thực tế ?

Mọi ý tưởng, gợi ý và phản hồi đều được chào đón.


4
Kiểm tra câu trả lời này: stackoverflow.com/questions/5867534/…
akirk

Câu trả lời:


209

Đối với những người vẫn đang đấu tranh với vấn đề này. Đây là cách tiếp cận tôi đã sử dụng với aws-sdk bản địa.

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

bên trong phương pháp bộ định tuyến của bạn: - ContentType phải được đặt thành loại nội dung của tệp hình ảnh

  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('succesfully uploaded the image!');
      }
  });

tệp s3_config.json là: -

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

2
[MissingRequiredParameter: Thiếu khóa cần 'chính' trong params]
Nichole A. Miler

1
Key: req.body.userId Tôi đã sử dụng userId làm khóa trong dữ liệu bài đăng ... nó đã có từ lâu ... nhưng bạn có thể khai báo bất kỳ chuỗi nào làm khóa. Để đảm bảo các tệp hiện có không bị ghi đè, hãy giữ khóa duy nhất.
Divyanshu Das

@Divyanshu Cảm ơn vì ví dụ hữu ích như vậy. Tôi có hai nghi ngờ: How to make S3 generates a unique KEY to prevent from overriding files?If I don't set the ContentType, when I download the files I won't be able to get the correct file?ý tôi là, tôi sẽ nhận được một tệp bị hỏng? Cảm ơn trước!
alexventuraio

2
Đường dẫn vị trí @Marklar về cơ bản là khóa - ví dụ: nếu tên nhóm của bạn là - bucketone và tên khóa là xyz.png, thì đường dẫn tệp sẽ là bucketone.s3.amazonaws.com/xyz.png
Divyanshu Das

2
@Divyanshu Cảm ơn vì câu trả lời tuyệt vời này! Nó đã giúp tôi rất nhiều. Tuy nhiên, tôi nghĩ ContentEncoding: 'base64'là không đúng vì new Buffer(..., 'base64')giải mã chuỗi mã hóa base64 thành biểu diễn nhị phân của nó.
Shuhei Kagawa

17

ok, đây là câu trả lời về cách lưu dữ liệu canvas vào tệp

về cơ bản nó lỏng lẻo như thế này trong mã của tôi

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
Đối tượng bộ đệm sẽ xuất hiện một lỗi "Bộ đệm không xác định" bạn có thể cho tôi giải pháp cho điều đó.
NaveenG

Tôi cũng nhận được lỗi tương tự. bạn có bất kỳ giải pháp hay không
Krishna

1
@NaveenG Đây là một ví dụ về nút, có thể bạn đang sử dụng JS thuần túy?
Pointi

7

Đây là mã từ một bài báo tôi đã xem qua, đăng bên dưới:

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;

Đọc thêm: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#upload-property

Tín dụng: https://medium.com/@mayneweb/upload-a-base64-image-data-from-nodejs-to-aws-s3-bucket-6c1bd945420f


4

Câu trả lời được chấp nhận hoạt động tốt nhưng nếu ai đó cần chấp nhận bất kỳ tệp nào thay vì chỉ hình ảnh thì regexp này hoạt động rất tốt:

/^data:.+;base64,/

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.