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設置屬性

 

 

 

 

 

讓我們繼續前行

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM