Nodejs保存上传的文件

问题描述 投票:0回答:3

我有一个应用程序,在该应用程序中,我想使用一些文件上传机制。

我的要求是:

上传文件后,其名称将更改为唯一的名称,如uuid4()。我稍后会将此名称存储在数据库中。

我写过类似的东西,但是我有几个问题:

const multer = require('multer');
const upload = multer();
router.post('/', middleware.checkToken, upload.single('file'), (req,res,next)=>{

    // key:
    // file : "Insert File Here"

    console.log("req:");
    console.log(req.file);
    const str = req.file.originalname
    var filename = str.substring(0,str.lastIndexOf('.'));
    // I will use filename and uuid for storing it in the database
    // I will generate unique uuid for the document and store the document
    // with that name
    var extension = str.substring(str.lastIndexOf('.') + 1, str.length);

    // HERE!

    res.status(200).json();

})

我已经看到了将其存储在diskStorage中的示例:

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, '/tmp/my-uploads')
    },
    filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now())
  }
})

var upload = multer({ storage: storage })

但是,据我所知,这是API调用之外的配置。这意味着我每次调用此API时都无法修改它。我想为文件指定不同的名称,我需要该名称(uuid)将该名称保存在数据库中。

我该如何保留这些功能?

node.js mongoose multer
3个回答
1
投票

感谢@Rashomon和@Eimran Hossain Eimon,我已经解决了这个问题。如果有人想知道解决方案,这里是:

const multer = require('multer');
var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        // the file is saved to here
        cb(null, '/PATH/TO/FILE')
    },
    filename: function (req, file, cb) {
        // the filename field is added or altered here once the file is uploaded
        cb(null, uuidv4() + '.xlsx')
    }
})
var upload = multer({ storage: storage })


router.post('/', middleware.checkToken, upload.single('file'), (req,res,next)=>{
    // the file is taken from multi-form and the key of the form must be "file"

    // visible name of the file, which is the original, uploaded name of the file
    const name = req.file.originalname;

    // name of the file to be stored, which contains unique uuidv4
    const fileName = req.file.filename;
    // get rid of the extension of the file ".xlsx"
    const file_id = fileName.substring(0, fileName.lastIndexOf('.'));

    // TODO
    // Right now, only xlsx is supported
    const type = "xlsx";

    const myObject = new DatabaseObject({
        _id : new mongoose.Types.ObjectId(),
        file_id: file_id,
        name : name,
        type: "xlsx"
    })

    myObject .save()
    .then(savedObject=>{
        // return some meaningful response
    }).catch(err=>{
        // return error response
    })
})

这解决了我当前的问题。谢谢你的帮助。为了将来的改进,我将添加错误案例:

  • 如果uuidv4返回一个已经存在的id(我认为由于该对象包含一些时间戳数据,它非常不可能),请重新运行重命名功能。
  • 如果保存到数据库时出错,我应该删除上传的文件以避免将来发生冲突。

如果你也有这些问题的解决方案,我非常感谢。


0
投票

我觉得你弄错了......你这么说

每次调用此API时都无法修改它。

但实际上,每次为每个文件调用filename。让我解释这部分代码......

filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now())
  }

这里看一下callback函数(用cb表示):

  • 回调函数中的第一个参数null就像约定。你总是将null作为回调函数中的第一个参数传递。 See this Reference
  • 第二个参数确定在destination文件夹中应该命名的文件。所以,在这里你可以指定任何函数,每次都可以返回一个唯一的文件名。

因为你正在使用mongoose ...我认为如果你在你的Schema中使用function uniqueFileName()实现你的mongoose method会更好(你要在其中保存文件路径)并在你的路由处理程序中调用它。 Learn More


0
投票
  1. 没必要。因为你正在使用时间戳。
  2. 如果保存到数据库时出错,您可以使用此代码删除上载的文件,以避免将来发生冲突。试试这个: const multer = require('multer'); const fs = require('fs'); // add this line var storage = multer.diskStorage({ destination: function (req, file, cb) { // the file is saved to here cb(null, '/PATH/TO/FILE') }, filename: function (req, file, cb) { // the filename field is added or altered here once the file is uploaded cb(null, uuidv4() + '.xlsx') } }) var upload = multer({ storage: storage }) router.post('/', middleware.checkToken, upload.single('file'), (req,res,next)=>{ // the file is taken from multi-form and the key of the form must be "file" // visible name of the file, which is the original, uploaded name of the file const name = req.file.originalname; // name of the file to be stored, which contains unique uuidv4 const fileName = req.file.filename; // get rid of the extension of the file ".xlsx" const file_id = fileName.substring(0, fileName.lastIndexOf('.')); // TODO // Right now, only xlsx is supported const type = "xlsx"; const myObject = new DatabaseObject({ _id : new mongoose.Types.ObjectId(), file_id: file_id, name : name, type: "xlsx" }) myObject .save() .then(savedObject=>{ // return some meaningful response }).catch(err=>{ // add this // Assuming that 'path/file.txt' is a regular file. fs.unlink('path/file.txt', (err) => { if (err) throw err; console.log('path/file.txt was deleted'); }); }) })

还看到NodeJS File System Doc

© www.soinside.com 2019 - 2024. All rights reserved.