node实现http上传文件进度条 -我们到底能走多远系列(37)

我们到底能走多远系列(37)

扯淡:

  又到了一年一度的跳槽季,相信你一定准备好了,每每跳槽,总有好多的路让你选,我们的未来也正是这一个个选择机会组合起来的结果,所以尽可能的找出自己想要的是什么再做决定。共勉!

 

主题:

  实现上传文件时,在页面中展现进度条的基本原理如图:

 

  1,客户端先发起上传文件请求,上传文件未结束前,后台实时的把已经上传的百分比存进session中(也可以使用像redis这样的数据库)。

  2,在上面这个过程中,客户端不断向服务端请求获取文件上传百分比,然后展现在页面上。

  3,直到全部上传完毕,上传文件响应返回。

 

1,上传文件:

  要实现上传文件进度条,先保证上传时页面不跳转,所以需要使用模拟ajax上传的方式。

  这儿就使用了比较简单的ajaxupload,在以前的 文章 中也有提到。

  关于页面不跳转上传文件可以参考阮一峰的文章: 参考

 

2,将文件上传比例放入session

  我这里使用了formidable,地址利用下面的代码就可以监控上传过程:

form.on('progress', function(bytesReceived, bytesExpected) {
});

  然后再里面将上传百分比放进session即可。这里session的实现可以阅读 上篇文章

上传文件的代码:

exports.jupload = function(sessions){
    console.log("jupload");
    return function(req, res) {
        var form = new formidable.IncomingForm();
        form.uploadDir = __dirname;
        form.parse(req, function(err, fields, files) {
            //res.writeHead(200, {'content-type': 'text/plain'});
            //res.write('Received upload:\n\n');
            var exts = files.ajaxfile.name.split('.');
            var ext = exts[1];
            var date = new Date();
            var ms = Date.parse(date);
            fs.renameSync(files.ajaxfile.path, __dirname +"/uploadfiletmp/" + ms +"." + ext);
        });
        var opts = {
            name : "uploadprogress",
            value : 0,
            expires : 500
        };

        sessions.setSession(req,res,opts);
        //文件上传中事件
        form.on("progress", function (bytesReceived, bytesExpected) {
            //console.log("progress!" + bytesReceived +"____" + bytesExpected);
            // 百分比
            var percent = Math.round(bytesReceived/bytesExpected * 100);
            var opts = {
                name : "uploadprogress",
                value : percent,
                expires : 500
            };
            // 存入
            sessions.setSession(req,res,opts);
        });
        form.on('end', function() {
            res.render("upload",{data : ""});
        });
    };
//    form.on("complete", function (err) {
//        console.log("complete!");
//    });
};

注意:上面的代码中监听的end事件,等到上传结束时才进行返回操作,是为了避免重新写headers的错误

http.js:704
    throw new Error('Can\'t set headers after they are sent.');
          ^
Error: Can't set headers after they are sent.

 

3,客户端不断请求获取文件上传百分比

  我们只要在页面上弄个定时,发起ajax请求百分比,然后判断百分比如果达到100,而停止。

下面是两个请求的js代码:

function aupload(fileElementId){
    $("#progress").css("width", "0%");
    // 发起上传文件请求
    $.ajaxFileUpload({
        url:"/jupload",
        fileElementId:fileElementId,
        success:function(){
            alert("上传成功");
        }
    });
    // 获取文件上传百分比
    getUploadProgress();
}

function getUploadProgress(){
    var progress = 0;
    $.ajax({
        url : "/uploadprogress",
        dataType: "json",
        success:function(msg){
            //百分比
            progress = msg.progress;
            $("#progress").css("width", progress +"%");
            if(progress < 100){
                // 继续调用
                setTimeout("getUploadProgress('/uploadprogress')",1);
            }
        }
    })
}

以及后台返回进度百分比的代码:

exports.uploadprogress = function(sessions){
    return function(req, res) {
        // 从session中获取
        var progress = sessions.getSession(req, "uploadprogress");
        console.log(progress+"---------------------");
        res.send({"progress":progress});
    }
};

 

4,页面上进度条的展现

这里使用了bootstrap

其中有一个Progress bars的插件:demo

下面代码就可以改变进度条的百分比了

$("#progress").css("width", progress +"%");

 

注意:这里不能使用attr方法,具体的区别是:

  css设置style里的样式
  attr设置属性

 

 

 

 

 

让我们继续前行

----------------------------------------------------------------------

努力不一定成功,但不努力肯定不会成功。

posted on 2014-02-09 14:01  每当变幻时  阅读(3581)  评论(4编辑  收藏  举报

导航