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   每当变幻时  阅读(3588)  评论(4编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示