如何使用Node.js将base64编码图像(string)直接上传到Google Cloud Storage存储桶?

目前,我正在使用@ google-cloud / storage NPM软件包将文件直接上传到Google云端存储分区。 这需要一些诡计,因为我只有图像的base64编码的string。 我不得不:

  • 解码string
  • 将其另存为一个文件
  • 将文件path发送到以下脚本以上传到Google云端存储
  • 删除本地文件

我想避免将文件存储在文件系统中,因为我使用的是Google App Engine,如果删除操作无论如何都不起作用,我不想在那里重载文件系统/将垃圾文件放在那里。 这就是我的上传脚本现在看起来像:

// Convert the base64 string back to an image to upload into the Google Cloud Storage bucket var base64Img = require('base64-img'); var filePath = base64Img.imgSync(req.body.base64Image, 'user-uploads', 'image-name'); // Instantiate the GCP Storage instance var gcs = require('@google-cloud/storage')(), bucket = gcs.bucket('google-cloud-storage-bucket-name'); // Upload the image to the bucket bucket.upload(__dirname.slice(0, -15) + filePath, { destination: 'profile-images/576dba00c1346abe12fb502a-original.jpg', public: true, validation: 'md5' }, function(error, file) { if (error) { sails.log.error(error); } return res.ok('Image uploaded'); }); 

是否有直接上传图像的base64编码的string,而不必将其转换为文件,然后使用path上传?

我相信解决scheme是使用bucket.upload函数包装在Google Cloud Node SDK中的bucket.uploadfunction。

我对于溪stream的经验很less,所以如果这不起作用的话,请耐心等待。

首先,我们需要将base64数据放入stream中。 为此,我们将包含stream库,从base64数据创build缓冲区,并将缓冲区添加到stream的末尾。

 var stream = require('stream'); var bufferStream = new stream.PassThrough(); bufferStream.end(new Buffer(req.body.base64Image, 'base64')); 

更多有关解码base64和创buildstream 。

然后,我们将把stream传file.createWriteStreamfile.createWriteStream函数创build的写入stream。

 var gcs = require('@google-cloud/storage')({ projectId: 'grape-spaceship-123', keyFilename: '/path/to/keyfile.json' }); //Define bucket. var myBucket = gcs.bucket('my-bucket'); //Define file & file name. var file = myBucket.file('my-file.jpg'); //Pipe the 'bufferStream' into a 'file.createWriteStream' method. bufferStream.pipe(file.createWriteStream({ metadata: { contentType: 'image/jpeg', metadata: { custom: 'metadata' } }, public: true, validation: "md5" })) .on('error', function(err) {}) .on('finish', function() { // The file upload is complete. }); 

有关file.createWriteStream , File docs , bucket.upload以及Node SDK中的bucket.upload方法代码的信息 。

所以上面代码的工作方式是定义你想要放入文件的桶,然后定义文件和文件名。 我们在这里不设置上传选项。 然后,我们将刚刚创build的bufferStreamvariablesfile.createWriteStream前面讨论过的file.createWriteStream方法。 在这些选项中,我们定义了要实现的元数据和其他选项。 直接看看Github上的Node代码来弄清楚它们是如何分解bucket.upload函数是非常有帮助的,并且推荐你这样做。 最后,我们附上一些事件,以便上传完成时以及何时出错。

发布我的答案版本以回应上面的@krlozadan的要求:

 // Convert the base64 string back to an image to upload into the Google Cloud Storage bucket var mimeTypes = require('mimetypes'); var image = req.body.profile.image, mimeType = image.match(/data:([a-zA-Z0-9]+\/[a-zA-Z0-9-.+]+).*,.*/)[1], fileName = req.profile.id + '-original.' + mimeTypes.detectExtension(mimeType), base64EncodedImageString = image.replace(/^data:image\/\w+;base64,/, ''), imageBuffer = new Buffer(base64EncodedImageString, 'base64'); // Instantiate the GCP Storage instance var gcs = require('@google-cloud/storage')(), bucket = gcs.bucket('my-bucket'); // Upload the image to the bucket var file = bucket.file('profile-images/' + fileName); file.save(imageBuffer, { metadata: { contentType: mimeType }, public: true, validation: 'md5' }, function(error) { if (error) { return res.serverError('Unable to upload the image.'); } return res.ok('Uploaded'); }); 

这对我来说工作得很好。 忽略前几行中的一些附加逻辑,因为它们只与我正在构build的应用程序有关。