express formidable(不使用body.parser) 多文件上传 请教
发布于 10 年前 作者 xiaoyuxiaoyu 11515 次浏览 最后一次编辑是 8 年前

由于新版本的express 使用:app.use(express.json());app.use(express.urlencoded());app.use(require(‘connect-multiparty’)()); //(connect-multiparty需要另外安装) 来代替app.use(express.bodyParser()); 那么我想着如何在不使用app.use(express.bodyParser({ keepExtensions: true, uploadDir: ‘./public/images’ }));的情况下,使用formidable来实现多文件上传呢?

问题来了看代码(代码是照着那个博客代码写的): app.js app.use(express.json()); app.use(express.urlencoded()); //app.use(express.multipart()); app.use(require(‘connect-multiparty’)()); //app.js中其他代码未列出 和 博客实例app.js代码是相同的。

upload.ejs:

  <%- include header %>
    <form method='post' action='/upload' enctype='multipart/form-data' >
         <input type="file" name='file1'/><br>
        <input type="file" name='file2'/><br>
        <input type="file" name='file3'/><br>
        <input type="file" name='file4'/><br>
        <input type="file" name='file5'/><br>
        <input type="submit" />
    </form>
  <%- include footer %>

index.js: 路由处理部分

var crypto = require('crypto'),   //可用其生成散列值来加密
fs = require('fs'),
User = require('../models/user.js');
var Post = require('../models/post.js');
var formidable = require('formidable');

  app.post('/upload', function(req, res){

    var form = new formidable.IncomingForm();

    form.uploadDir = './public/images/';    //上传目录
    form.keepExtensions = true;             //保留后缀格式
    form.maxFieldsSize = 2*1024*1024;       //文件大小
    console.log('new formidable',form);
    return res.redirect('/');              //这是为了测试
    form.parse(req, function(err, fields, files){

        /*if (err){
         req.flash('error', '文件上传失败');
         return res.redirect('/upload');
         }*/

        //console.log('formidable fields:', fields);
        /* for (var i in files){
         if (files[i].size == 0){
         //使用同步方式删除一个文件
         fs.unlinkSync(files[i].path);
         console.log('file path:',files[i].path);
         console.log('success remove a empty file');
         }else{
         var target_path = './public/images/' + files[i].name;  //这里重名时  一定要注意
         //使用同步方式重命名一个文件
         fs.renameSync(files[i].path, target_path);
         console.log('successfully rename a file');
         }
         }*/
       // req.flash('success', '文件上传成功!');
        //res.redirect('/upload');

    });

问题:如果没有在 form.parse()前使用return 那么点击上传时, 页面会一直显示正在加载,估计是异步哪里的问题。 接下来我用app.post(’/upload’, function(req, res){ console.log(‘new formidable’,form); return res.redirect(’/’); } 这个测试 ,文件可以上传,并且打印出的信息:

  new formidable { domain: null,

_events: {}, _maxListeners: 10, error: null, ended: false, maxFields: 1000, maxFieldsSize: 2097152, keepExtensions: false, uploadDir: ‘C:\Users\ADMINI~1\AppData\Local\Temp’, //看这里 encoding: ‘utf-8’, headers: null, type: null, hash: false, multiples: false, bytesReceived: null, bytesExpected: null, _parser: null, _flushing: 0, _fieldsSize: 0, openedFiles: [] }

通过以上信息我们可以看到 文件上传到’C:\Users\ADMINI~1\AppData\Local\Temp ,然后我查找这个路径,发现文件确实上传到这里了。 然后我有在app.post(’/upload’, function(req, res){

    var form = new formidable.IncomingForm();

    form.uploadDir = './public/images/';    //上传目录
    form.keepExtensions = true;             //保留后缀格式
    form.maxFieldsSize = 2*1024*1024;       //文件大小
    console.log('new formidable',form);
    return res.redirect('/');              //这是为了测试}  

测试后发现打印出来的 uploadDir: ‘./public/images/’, 说明上传路径改变了 但是文件还是保存在’C:\Users\ADMINI~1\AppData\Local\Temp。

是我的思路错了么? 还是不使用bodyParser()就不能使用forimidable . 到底该如何将文件上传到指定的目录呢?并且要删掉那些上传的空文件??求各位大大赐教 不胜感激!! 要上班走了 ,写的匆忙 见谅!!

3 回复

如果有什么思路,也请赐教

uploadDir目录要加上绝对路径,_dirname

我不知道你是什么问题,不过我贴我上传文件的模块给你吧,事实上,上传多个文件有专门的module,我用的是busboy

router.post('/upload',function(req,res){
  req.pipe(req.busboy)
  //要上传的文件数目
  var fileNum = 3;
  var fileCount = 0;
  var filepath = path.join(path.normalize(__dirname + '/..'),'public','images')
  req.busboy.on('file',function(fieldname,file,filename){
  //  console.log('++upload ' + filepath+'/'+filename)
    var fstream
    if(filename !== ""){
      fstream = fs.createWriteStream(filepath+'/'+filename.trim());
      file.pipe(fstream);
    }
    fstream.on('close', function () {
      if(++fileCount == fileNum)
        res.redirect('/');
    });
  })
回到顶部