由于新版本的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 . 到底该如何将文件上传到指定的目录呢?并且要删掉那些上传的空文件??求各位大大赐教 不胜感激!! 要上班走了 ,写的匆忙 见谅!!
如果有什么思路,也请赐教
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('/');
});
})