繁体   English   中英

Nodejs - 如何保存从前端发送到公共文件夹的文件 object 而不使用像 multer 这样的中间件?

[英]Nodejs - how can I save a file object sent from frontend to the public folder without using middleware like multer?

我有一个 React 客户端应用程序和一个 Nodejs 后端。

我正在尝试将字符串化的 json 和一些 pdf 文件(由react-dropzone从客户端上传)作为 formdata/multipart 在这样的 put 请求中发送:

let formData = new FormData()

formData.append('user', JSON.stringify(jsonData))
formData.append('file_1', user.file_1)
formData.append('file_2', user.file_2)

在我的 Nodejs 后端,我使用 multer 提取表单数据:

let multerInstance = multer();
userRouter.put('/user/:user_id', validateJwt, multerInstance.any(), putUser);

我像这样提取formdata:

const formData = req.body;
const user = JSON.parse(formData.user);
const files = req.files; // here I have file_1 and file_2 as file objects

但是,如果我使用 multer 保存文件,我必须像这样在中间件中传递配置设置:

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './public/uploads');
  },
  filename: function (req, file, cb) {
    var fileFormat = file.originalname.split('.');
    cb(null, file.fieldname + '-' + Date.now() + '.' + fileFormat[fileFormat.length - 1]);
  },
});

let multerInstance = multer({
  storage: storage,
});

let multerInstance = multer();
userRouter.put('/user/:user_id', validateJwt, multerInstance.any(), putUser);

我不想这样做,因为我想决定是否在 putUser 中执行上传操作(保存到 /public/uploads),而不是在 multer 中间件中设置目标(无论如何,它将在 putUser 之前运行)

我怎样才能做到这一点?

很高兴找到使用fs.writeFile的解决方案

首先,在没有任何配置的情况下在这样的路由上使用 multer,以便它仅用作 formdata 移相器:

let multerInstance = multer();
userRouter.put('/user/:user_id', validateJwt, multerInstance.any(), putUser);

接下来,获取路由中带有req.files的文件,通过multer分阶段的文件将如下所示:

{
    fieldname: 'myField',
    originalname: 'file_1.pdf',
    encoding: '7bit',
    mimetype: 'application/pdf',
    buffer: <Buffer 25 50 44 46 2d 31 2e 33 0a 25 c4 e5 f2 e5 eb a7 f3 a0 d0 c4 c6 0a 34 20 30 20 6f 62 6a 0a 3c 3c 20 2f 4c 65 6e 67 74 68 20 35 20 30 20 52 20 2f 46 69 ... 51728 more bytes>,
    size: 51778
}

由于我观察到文件中有一个缓冲区,我可以使用fs模块将文件写入目标路径,以便可以在路由内完成上传操作。

const files = req.files

const uploadFiles = files.map((file) => {
   return new Promise(function (resolve, reject) {
       let fileFormat = file.originalname.split('.');
       let savePath = file.fieldname + '-' + Date.now() + '.' + fileFormat[fileFormat.length - 1];
       fs.writeFile('./public/uploads/' + savePath, file.buffer, function (err) {
         if (err) {
            return reject();
         }

         return resolve();
      });
   });
});

await Promise.all(uploadFiles);

您可以配置 multer 并仅在准备好时从putUser()内部调用它。 如果您将自己的next() function 提供给中间件而不是标准中间件,它会在完成时调用您的 function 而不是下一条路由。

您需要软件来读取正文并解析多部分 mime,而自己编写它并不好玩,这就是为什么我建议您使用现有软件进行解析的原因。

以下是关于它的外观的一般想法:

function putUser(req, res, next) {
    // do a bunch of your own logic here
    if (iWantToProcessFile) {
        // call multer middleware to process form data
        let multerFn = multerInstance.any();
        multerFn(req, res, function(err) {
            if (err) return next(err);
            // use multer data on req object now to finish your request
        });
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM