如何使用 multer 清理临时文件

How to cleanup temp files using multer

我的 nodejs 应用程序接受来自用户的文件上传,该权限由 express 中间件强制执行,并且它使用 multer

一个典型的路由进行身份验证,检查用户是否被允许,然后进行导入,例如:

router.post('/:id/import', passport.authenticate('jwt', { session: false }), permit('admin'), function(req, res, next) {
    MyClass.doImport(req.file.path).then(function(result) {
        res.json(result);
    }).catch(function(error) {
        res.status(500).json(error);
    });
});

当没有错误时,这很好用,导入功能会删除文件。但是如果出现错误(例如无效或未经许可的用户),上传的文件将被创建并保留在磁盘上。

在所有权限中间件都成功 运行 之前,我不想在磁盘上创建任何文件。我试过使用 multer 作为链的最末端,即:

var app = express();

app.use( // ...

app.use(passport.initialize());
app.use(multer({dest:'./tmp/'}).single('file'));

但是在验证错误时,我仍然在 tmp 中得到一个文件。

如何避免在所有其他中间件通过之前在磁盘上创建文件?

如果那不可能,我可以添加一个中间件函数吗?运行只有在有文件附件并且上游有错误时才可以?

移动您的 multer 中间件,使其仅在相关路由处理程序之前执行。这样,如果有任何其他中间件 "rejects" 请求,您就不会留下临时文件。例如:

function isLoggedIn(req, res, next) {
  if (req.isAuthenticated())
    return next();
  res.redirect('/');
}
var fileUpload = multer({dest:'./tmp/'}).single('file');

var app = express();
// ...
app.use(passport.initialize());
// ...
app.put('/upload', isLoggedIn, fileUpload, function(req, res) {
  // use `req.file`
});

您也可以结合使用 cron 和 'fs' 模块来定期执行此任务。您只需要将此代码放入 app.js 即可。 我必须定期删除所有临时文件和文件夹。

var fs = require('fs');
var CronJob = require('cron').CronJob;
var temp_folder_path = path.join(__dirname, 'public', 'uploads');

     /*
        Seconds: 0-59
        Minutes: 0-59
        Hours: 0-23
        Day of Month: 1-31
        Months: 0-11
        Day of Week: 0-6 // 0 = Sunday
       * cronjob for deleting temp files from public/upload folders
       * this cronjob runs from Monday through Friday at midnight 12:00 
    */
    new CronJob('00 00 00 * * 1-5', function () {
    console.log('deleting all temporary file from public/uploads/*');
    deleteFolderRecursive(temp_folder_path)
}, null, true, 'America/Los_Angeles');


// Used for deleting all files and sub-folders from 'public/upload/*'
// Multer : stores temporary files in this folder
var deleteFolderRecursive = function (path) {
    if (fs.existsSync(path)) {
        fs.readdirSync(path).forEach(function (file, index) {
            var curPath = path + "/" + file;
             if (fs.lstatSync(curPath).isDirectory()) { // recurse
                deleteFolderRecursive(curPath);
                fs.rmdirSync(curPath);
            } else { // delete file
                fs.unlinkSync(curPath);
            }
        });
    }
};