Node.js 如何使用NodeJS将文件上载到Amazon AWS3?

Node.js 如何使用NodeJS将文件上载到Amazon AWS3?,node.js,reactjs,amazon-web-services,amazon-s3,react-router,Node.js,Reactjs,Amazon Web Services,Amazon S3,React Router,我正在尝试从我正在使用的MERN应用程序上载文件。我几乎完成了NodeJS的后端部分 该应用程序将允许用户将图像(jpg、jpeg、png、GIF等)上传到我创建的AmazonAWSS3存储桶中 好吧,让我们这样说吧。我创建了一个助手: const aws = require('aws-sdk'); const fs = require('fs'); // Enter copied or downloaded access ID and secret key here const ID = p

我正在尝试从我正在使用的MERN应用程序上载文件。我几乎完成了NodeJS的后端部分

该应用程序将允许用户将图像(jpg、jpeg、png、GIF等)上传到我创建的AmazonAWSS3存储桶中

好吧,让我们这样说吧。我创建了一个助手:

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

// Enter copied or downloaded access ID and secret key here
const ID = process.env.AWS_ACCESS_KEY_ID;
const SECRET = process.env.AWS_SECRET_ACCESS_KEY;

// The name of the bucket that you have created
const BUCKET_NAME = process.env.AWS_BUCKET_NAME;

const s3 = new aws.S3({
  accessKeyId: ID,
  secretAccessKey: SECRET
});

const uploadFile = async images => {
  // Read content from the file
  const fileContent = fs.readFileSync(images);

  // Setting up S3 upload parameters
  const params = {
    Bucket: BUCKET_NAME,
    // Key: 'cat.jpg', // File name you want to save as in S3
    Body: fileContent
  };

  // Uploading files to the bucket
  s3.upload(params, function(err, data) {
    if (err) {
      throw err;
    }
    console.log(`File uploaded successfully. ${data.Location}`);
  });
};

module.exports = uploadFile;
这个助手接受我的三个环境变量,它们是bucket的名称、keyId和secret key

从表单添加文件时(最终将添加到前端),用户将能够发送多个文件

现在,我当前的投递路线与此完全相同:

req.body.user = req.user.id;
req.body.images = req.body.images.split(',').map(image => image.trim());
const post = await Post.create(req.body);

res.status(201).json({ success: true, data: post });
这一点非常有用,但它将req.body.images作为一个字符串,每个图像用逗号分隔。将从Windows目录弹出窗口中选择的许多文件上载(到AWS S3)的正确方法是什么?。我尝试过这样做,但没有成功:/

// Add user to req,body
req.body.user = req.user.id;
uploadFile(req.body.images);
const post = await Post.create(req.body);

res.status(201).json({ success: true, data: post });

谢谢,希望你们能帮我解决这个问题。现在我正在用Postman进行测试,但稍后会通过表单发送文件。

您可以为每个文件多次调用uploadFile:

try{
    const promises= []
    for(const img of images) {
          promises.push(uploadFile(img))
        }
    await Promise.all(promises)
    //rest of logic

}catch(err){ //handle err }
在旁注中,您应该在承诺中扭曲S3.upload:

const AWS = require('aws-sdk')

const s3 = new AWS.S3({
  accessKeyId: process.env.AWS_ACCESS_KEY,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
})

module.exports = ({ params }) => {
  return new Promise((resolve, reject) => {
    s3.upload(params, function (s3Err, data) {
      if (s3Err) return reject(s3Err)
      console.log(`File uploaded successfully at ${data.Location}`)
      return resolve(data)
    })
  })
}
另外,如果您希望避免后端处理上传,您可以使用并让客户端浏览器处理上传,从而节省服务器资源


还有一件事,您的Post对象应该只包含媒体的URL,而不是媒体本身。

您的代码向我抛出了一个错误“未定义图像”。我尝试使用const images=req.body.images,但没有成功。代码仅供参考,我不知道您是如何将数据发送到服务器的。req.body.images应该是一个图像数组。(我的猜测是您将二进制数据进行base64编码并发送)。这可能会有帮助,
// Setting up S3 upload parameters
    const params = {
        Bucket: bucket, // bucket name
        Key: fileName, // File name you want to save as in S3
        Body: Buffer.from(imageStr, 'binary'), //image must be in buffer
        ACL: 'public-read', // allow file to be read by anyone
        ContentType: 'image/png', // image header for browser to be able to render image
        CacheControl: 'max-age=31536000, public' // caching header for browser
    };

    // Uploading files to the bucket
    try {
        const result = await s3.upload(params).promise();
        return result.Location;
    } catch (err) {
        console.log('upload error', err);
        throw err;
    }