Multer returns req.file 未定义,并且 req.file.location 在将文件上传到 aws 存储桶时未定义位置

Multer returns req.file as undefined, and req.file.location as location undefined while uploading file to aws bucket

我正在尝试将图像上传到 s3 存储桶。并在网上尝试了很多解决方案,但我得到了上述错误。我不想在本地存储图像,而是想将它们直接上传到 s3 存储桶。任何帮助将不胜感激。

这是Upload.js文件

const AWS = require('aws-sdk');
const Keys = require('../Config/dev');
const { v4: uuidv4 } = require('uuid');
const axios = require('axios').default;
const multer = require('multer');
const multerS3 = require('multer-s3');


const s3 = new AWS.S3({
  accessKeyId: Keys.accessKeyId,
  secretAccessKey: Keys.secretAccessKey,
  region : 'ap-south-1'
});

var upload = multer({
  storage: multerS3({
    s3: s3,
    bucket: 'thebucketname',
    acl : "public-read",
    metadata: function (req, file, cb) {
      cb(null, {fieldName: file.fieldname});
    },
    key: function (req, file , cb){
        cb(new Date().toISOString().replace(/[-T:\.Z]/g, "") + file.originalname);
    }
  })
});

module.exports = upload;

这是路由器代码

const express = require('express');
const Router = express.Router();
const controllers = require('../controllers/controllers.js');
const uploader = require('../controllers/Upload');
const singleUpload = uploader.single('img');

Router.post('/single-image',(req, res)=>{
    singleUpload(req, res , (err)=>{
        if(!req.file){
            console.log(req.file);
        }else
        {
        console.log(req.file);
        return res.json({'imageUrl': req.file.location});
        }
    });
});

这就是我使用 postman 处理 api 请求的方式。我还在邮递员的 Headers 中将 Content-Type 设置为 Multipart/form-data 。当我执行此操作时,req.file 出现错误 "undefined"。

此外,如果我使用

 app.use(multer({dest:'./public/uploads/'}).single('file'));

我的文件存储在 'uploads' 文件夹中,但随后出现错误 "req.file.location undefined",并且文件未上传到 aws。

首先,如果您想将文件上传到 s3 而不是将其存储在您的服务器上,您可以 store the uploaded file as an in-memory buffer 而不是将其写入您的服务器然后上传到 s3。 注意:对于大文件或大量小文件,不建议使用这种内存方法,因为您需要确保您的服务器有足够的内存来处理上传。

然后你可以将缓冲区传递给 s3 上传函数。我不太了解您显然使用过的名为 multer-s3 的软件包,所以我没有使用它。我已经为一组文件制作了它,但它也应该适用于单个文件。我将您的代码与我的一些代码结合起来,得出以下结果:

//aws-sdk for node
const AWS = require('aws-sdk');
AWS.config.update({ region: <your region here> });

//S3
const S3 = new AWS.S3({});

const express = require('express');
const Router = express.Router();
const controllers = require('../controllers/controllers.js');
const uploader = require('../controllers/Upload');

//import multer
const multer = require("multer");



//make multer ready for in-memory storage of uploaded file
const multerMemoryStorage = multer.memoryStorage();
const multerUploadInMemory = multer({
    storage: multerMemoryStorage
});

//using multer.single as a middleware is what I prefer
Router.post('/single-image',multerUploadInMemory.single("filename"),async(req, res)=>{

    try{

        if(!req.file || !req.file.buffer){
            throw new Error("File or buffer not found");
        }

        const uploadResult = await S3.upload({
                    Bucket: "yourBucketName",
                    Key: "WhateverKeynameYouWantToGive",
                    Body: req.file.buffer,
                    ACL: 'public-read'
                }).promise();

        console.log(`Upload Successful!`);

        res.send({
            message: "file uploaded"
        })



    }catch(e){
        console.error(`ERROR: ${e.message}`);

        res.status(500).send({
            message: e.message
        })
    }

});

您可以先使用 console.log(req.file) 查看它是否未定义(它不应该是),然后您可以检查您是否在文件中获取缓冲区 属性。

另外,它在 "warning" here 中说你永远不应该将 multer 添加为全局中间件,所以 app.use(multer({dest:'./public/uploads/'}) 是一个禁忌。