我有一个应用程序,在该应用程序中,我想使用一些文件上传机制。
我的要求是:
上传文件后,其名称将更改为唯一的名称,如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)将该名称保存在数据库中。
我该如何保留这些功能?
感谢@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
})
})
这解决了我当前的问题。谢谢你的帮助。为了将来的改进,我将添加错误案例:
如果你也有这些问题的解决方案,我非常感谢。
我觉得你弄错了......你这么说
每次调用此API时都无法修改它。
但实际上,每次为每个文件调用filename
。让我解释这部分代码......
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
这里看一下callback
函数(用cb
表示):
null
就像约定。你总是将null
作为回调函数中的第一个参数传递。 See this Referencedestination
文件夹中应该命名的文件。所以,在这里你可以指定任何函数,每次都可以返回一个唯一的文件名。因为你正在使用mongoose ...我认为如果你在你的Schema中使用function uniqueFileName()
实现你的mongoose method
会更好(你要在其中保存文件路径)并在你的路由处理程序中调用它。 Learn More
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');
});
})
})