【问题标题】:Multer returns req.file as undefined, and req.file.location as location undefined while uploading file to aws bucket在将文件上传到 aws 存储桶时,Multer 返回 req.file 为未定义,req.file.location 作为位置未定义
【发布时间】:2020-09-20 16:13:07
【问题描述】:

我正在尝试将图像上传到 s3 Bucket。并在网上尝试了许多解决方案,但我得到了上述错误。我不想在本地存储图像,而是想直接将它们上传到 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});
        }
    });
});

这就是我使用邮递员进行 api 请求的方式。我还在邮递员的标头内将 Content-Type 设置为 Multipart/form-data 。执行此操作时,我收到 req.file 的错误“未定义”。

另外,如果我使用

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

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

【问题讨论】:

    标签: node.js amazon-s3 file-upload error-handling multer-s3


    【解决方案1】:

    首先,如果您想将文件上传到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) 来查看它是否未定义(它不应该是),然后您可以检查您是否在文件中获取了缓冲区属性。

    此外,它在“警告”here 中说您永远不应该将 multer 添加为全局中间件,因此 app.use(multer({dest:'./public/uploads/'}) 是禁忌。

    【讨论】:

    • 谢谢你这工作完全正常!但我很好奇为什么我的代码不起作用?您发现我所做的事情有什么问题吗?
    • 老实说,我看不出为什么 req.file 应该在您的代码中未定义,也无法说出来,因为我不知道到底是什么/controllers/Upload 您正在导入。但是根据他们的文档,用户 multer 的理想方式是作为特定于端点的中间件,而我只是这样做了。
    • 这很有见地。谢谢!
    • @AnujPancholi 嗨,你能看看这个问题吗?非常感谢任何可能的帮助。 stackoverflow.com/questions/65465145/…
    猜你喜欢
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 2020-11-01
    • 2021-10-02
    相关资源
    最近更新 更多