我們到底能走多遠系列(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設置屬性
讓我們繼續前行
----------------------------------------------------------------------
努力不一定成功,但不努力肯定不會成功。