通过jQuery fileupload插件和nodejs formidable插件实现文件异步上传,并且可以显示文件上传的进度。

1、插件准备

jquery fileuplaod:下载地址:https://github.com/blueimp/jQuery-File-Upload/tags

formidable:下载及安装:https://github.com/felixge/node-formidable

源码中使用了Express框架:https://github.com/visionmedia/express

2、前端代码

先上一个上传的页面

20140226113736203

图中“异步上传“的选择文件Element的ID为fileupload,因为使用了jquery fileupload插件,js代码就比较简单了,如下:

 

$('#fileupload').fileupload({  
       url: '/upload',  
       dataType: 'json',  
       //autoUpload: false,  
       //acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,  
       maxFileSize: 5000000, // 5 MB  
       // Enable image resizing, except for Android and Opera,  
       // which actually support image resizing, but fail to  
       // send Blob objects via XHR requests:  
       disableImageResize: /Android(?!.*Chrome)|Opera/  
           .test(window.navigator.userAgent),  
       previewMaxWidth: 100,  
       previewMaxHeight: 100,  
       previewCrop: true  
   }).on('fileuploadadd', function (e, data) {  
       data.context = $('
').appendTo('#files'); $.each(data.files, function (index, file) { var node = $('

') .append($('').text(file.name)); //if (!index) { // node // .append('
') // .append(uploadButton.clone(true).data(data)); //} node.appendTo(data.context); }); }).on('fileuploadprocessalways', function (e, data) { var index = data.index, file = data.files[index], node = $(data.context.children()[index]); if (file.preview) { node .prepend('
') .prepend(file.preview); } if (file.error) { node .append('
') .append($('').text(file.error)); } if (index + 1 === data.files.length) { data.context.find('button') .text('Upload') .prop('disabled', !!data.files.error); } }).on('fileuploadprogressall', function (e, data) { var progress = parseInt(data.loaded / data.total * 100, 10); $('#progress .progress-bar').css( 'width', progress + '%' ); }).on('fileuploaddone', function (e, data) { $.each(data.result.files, function (index, file) { if (file.url) { var link = $('') .attr('target', '_blank') .prop('href', file.url); $(data.context.children()[index]) .wrap(link); } else if (file.error) { var error = $('').text(file.error); $(data.context.children()[index]) .append('
') .append(error); } }); }).on('fileuploadfail', function (e, data) { $.each(data.files, function (index, file) { var error = $('').text('File upload failed.'); $(data.context.children()[index]) .append('
') .append(error); }); }).prop('disabled', !$.support.fileInput) .parent().addClass($.support.fileInput ? undefined : 'disabled');

3、服务端代码
基于Node平台,使用formidable插件,轻松实现文件上传,上传的文件保存在了tmp/文件夹下,如下:

exports.upload = function(req, res) {  
    // parse a file upload  
    var form = new formidable.IncomingForm(),files=[],fields=[],docs=[];  
    console.log('start upload');  
      
    //存放目录  
    form.uploadDir = 'tmp/';  
  
    form.on('field', function(field, value) {  
        //console.log(field, value);  
        fields.push([field, value]);  
    }).on('file', function(field, file) {  
        console.log(field, file);  
        files.push([field, file]);  
        docs.push(file);  
  
  
        var types = file.name.split('.');  
        var date = new Date();  
        var ms = Date.parse(date);  
        fs.renameSync(file.path, "tmp/files" + ms + '_'+file.name);  
    }).on('end', function() {  
        console.log('-> upload done');  
        res.writeHead(200, {  
            'content-type': 'text/plain'  
        });  
        var out={Resopnse:{  
            'result-code':0,  
            timeStamp:new Date(),  
        },  
        files:docs  
        };  
        var sout=JSON.stringify(out);  
        res.end(sout);  
    });  
  
    form.parse(req, function(err, fields, files) {  
        err && console.log('formidabel error : ' + err);  
  
        console.log('parsing done');  
    });  
  
};  

这样就实现了文件的异步上传,点击下载源码
源码下载