Node.js實(shí)現(xiàn)兼容IE789的文件上傳進(jìn)度條
Nodejs對(duì)文件上傳的處理
在Express4里req.files已經(jīng)是undefined
了;現(xiàn)在用的最多的可能就是formidable
了,你知道了它有個(gè)progress
事件,于是心中大喜,低版本IE的進(jìn)度條有戲了;OK,試一下:
form .on('error',function(err){ console.log(err); }) .on('aborted',function(){ console.log('aborted'); }) .on('progress',function(bytesReceived, bytesExpected){ var n=parseInt(parseFloat(bytesReceived/bytesExpected).toFixed(2)*100); console.log(n); });
是的,你很高興的看到了,控制臺(tái)按照預(yù)期打印了一串進(jìn)度值;那么,再進(jìn)一步;
form .on('progress',function(bytesReceived, bytesExpected){ var n=parseInt(parseFloat(bytesReceived/bytesExpected).toFixed(2)*100); res.write('<script>window.parent.call('+n+')</script>'); //無(wú)刷新上傳,你們懂的 console.log(n); });
call
方法即在頁(yè)面上顯示進(jìn)度值;很不幸,你只能看到最后的100%,看不到上傳具體詳細(xì)的進(jìn)度值;再探...
接下來(lái)?yè)Q個(gè)思路,試一下,將進(jìn)度值保存到session
里,額外加一個(gè)請(qǐng)求來(lái)輪詢這個(gè)進(jìn)度值,哎喲,不錯(cuò)哦!為了保證你請(qǐng)求的進(jìn)度值是你這次上傳的進(jìn)度值而不是其他上傳的進(jìn)度值,需要在上傳的請(qǐng)求里和額外的請(qǐng)求里約定一個(gè)token
值;現(xiàn)在又來(lái)一個(gè)問(wèn)題就是怎么在請(qǐng)求的時(shí)候得到這個(gè)token
,由于文件上傳的請(qǐng)求體在Request Payload
里,所以req.body
拿不到帶過(guò)去的值,我也不想去解析這堆了,當(dāng)然我也解析不了;放在url
里最好,問(wèn)題在于有時(shí)候得刷新兩次來(lái)刷新token
,不好!不得已,我還是放在cookie
里吧!
var cookies=function () { var cks=req.headers.cookie.split(';'),obj={}; for(var i=0;i<cks.length;i++){ obj[cks[i].split('=')[0].replace(/\s+/ig,'')]=unescape(cks[i].split('=')[1]); } return obj; }(); var queryToken=cookies.__token__; form .on('progress',function(bytesReceived, bytesExpected){ var n=parseInt(parseFloat(form.bytesReceived/form.bytesExpected).toFixed(2)*100); if (req.session['file'+queryToken]) { req.session['file'+queryToken].percent=n; }else{ req.session['file'+queryToken]={ token:queryToken, percent:n } }; console.log(n); });
為了IE789,我來(lái)輪詢進(jìn)度值了,原諒我,其實(shí)我的心很痛;
var getData=function(){ $.post('/uploader',{ getfileinfo:1, uploadtoken:utils.cookie.getCookie('__token__') }) .then(function(data){ console.log(data); if (data.mes<0) { getData(); }else{ var pros=data.info; call(pros.percent); if (pros.percent!='100') { getData(); }; }; }); } getData();
call
方法即在頁(yè)面上顯示進(jìn)度值;很不幸,你只能看到最后的100%,看不到上傳具體詳細(xì)的進(jìn)度值;再探...
好吧,我又一次淪陷了;不過(guò)還是感覺(jué)不對(duì)勁,ajax輪詢沒(méi)有問(wèn)題,問(wèn)題在于session
里要等到上傳完畢才有值,所以只能看到100%,看不到詳細(xì)進(jìn)度值;我是否可以認(rèn)為,在progress里,之前的res.write
和這次的req.session
被掛起了呢,但是它又保存了每次的執(zhí)行結(jié)果,直到progress
完再釋放,所以只能看到100%;沒(méi)心情看formidable
的源碼,當(dāng)然我也看不咋懂,我就先這么認(rèn)為吧!
既然ajax
輪詢沒(méi)問(wèn)題,那么就是保存到session
不得勁了;實(shí)在不成,放到global
里試試吧,總不會(huì)往全局對(duì)象里塞個(gè)值也會(huì)掛起吧;稍作改動(dòng)放到global
里:
form .on('progress',function(bytesReceived, bytesExpected){ var n=parseInt(parseFloat(form.bytesReceived/form.bytesExpected).toFixed(2)*100); if (global['file'+queryToken]) { global['file'+queryToken].percent=n; }else{ global['file'+queryToken]={ token:queryToken, percent:n } }; console.log(n); });
繼續(xù)輪詢。
漂亮,完全就是那么回事!在chrome里看到的和HTML5的進(jìn)度一個(gè)效果,只是在IE789里會(huì)有點(diǎn)卡頓的感覺(jué),不過(guò)還是能看到詳細(xì)的進(jìn)度值的;畢竟老瀏覽器身子骨不咋地,你們懂的;還有,每次上傳都往global
里塞值,怎么也得適當(dāng)?shù)那謇硪幌掳?,文件上傳完畢,轉(zhuǎn)移到指定目錄后global['file'+queryToken]=null
;
然而,輪詢,就是一個(gè)接一個(gè)好多好多的請(qǐng)求,這里也許會(huì)出問(wèn)題;要不限制一下吧,間隔500ms請(qǐng)求一次進(jìn)度值;恩,IE789進(jìn)度條就這么解決了,說(shuō)好的丟掉flash;雖然這個(gè)輪詢可以兼容所有瀏覽器,但畢竟要浪費(fèi)那么多請(qǐng)求,還是判斷下,在IE789以外繼續(xù)HTML5吧!
其實(shí)衡量一下,額外加個(gè)flash上傳和額外的請(qǐng)求,哪個(gè)更值呢,原諒我不懂flash,就不多說(shuō)了,反正我很不喜歡在頁(yè)面上加一下額外的文件;
總結(jié)
關(guān)于文件上傳的組件,還有很多的細(xì)節(jié)處理,本想弄一個(gè)JS文件的,后來(lái)一想,為了可復(fù)用性更強(qiáng),還是作為一個(gè)獨(dú)立的頁(yè)面搞比較好,需要上傳的地方,iframe一下就行了,肯定比弄一個(gè)JS文件要好很多。以上就是這篇文章的全部?jī)?nèi)容,希望能夠?qū)Υ蠹业膶W(xué)習(xí)或者工作帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流。
- js HTML5 Ajax實(shí)現(xiàn)文件上傳進(jìn)度條功能
- PHP中使用Session配合Javascript實(shí)現(xiàn)文件上傳進(jìn)度條功能
- JS插件plupload.js實(shí)現(xiàn)多圖上傳并顯示進(jìn)度條
- js實(shí)現(xiàn)帶進(jìn)度條提示的多視頻上傳功能
- PHP + plupload.js實(shí)現(xiàn)多圖上傳并顯示進(jìn)度條加刪除實(shí)例代碼
- 原生javascript上傳圖片帶進(jìn)度條【實(shí)例分享】
- 利用Plupload.js解決大文件上傳問(wèn)題, 帶進(jìn)度條和背景遮罩層
- 原生JS上傳大文件顯示進(jìn)度條 php上傳文件代碼
- node.js實(shí)現(xiàn)帶進(jìn)度條的多文件上傳
- JS+html5實(shí)現(xiàn)異步上傳圖片顯示上傳文件進(jìn)度條功能示例
相關(guān)文章
Nodejs進(jìn)階:如何將圖片轉(zhuǎn)成datauri嵌入到網(wǎng)頁(yè)中去實(shí)例
這篇文章主要介紹了Nodejs進(jìn)階:如何將圖片轉(zhuǎn)成datauri嵌入到網(wǎng)頁(yè)中去,有興趣的可以了解一下。2016-11-11npm安裝windows-build-tools卡在Successfully?installed?Python2.7
這篇文章主要介紹了npm安裝windows-build-tools卡在Successfully?installed?Python2.7的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10node+express實(shí)現(xiàn)分頁(yè)效果
這篇文章主要為大家詳細(xì)介紹了node+express實(shí)現(xiàn)分頁(yè)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06node.js實(shí)現(xiàn)簡(jiǎn)單登錄注冊(cè)功能
這篇文章主要為大家詳細(xì)介紹了node.js實(shí)現(xiàn)簡(jiǎn)單登錄注冊(cè)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04如何使用?Node.js?將?MongoDB?連接到您的應(yīng)用程序
NoSQL?數(shù)據(jù)庫(kù)對(duì)于處理大量分布式數(shù)據(jù)非常有用,我們可以在這個(gè)數(shù)據(jù)庫(kù)中存儲(chǔ)信息,對(duì)其進(jìn)行管理,這篇文章主要介紹了使用?Node.js?將?MongoDB?連接到您的應(yīng)用程序,需要的朋友可以參考下2022-09-09Nodejs實(shí)現(xiàn)WebSocket代碼實(shí)例
這篇文章主要介紹了Nodejs實(shí)現(xiàn)WebSocket代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05Node.js中MongoDB插入數(shù)據(jù)的實(shí)現(xiàn)方法
在Node.js中,可以使用MongoDB原生驅(qū)動(dòng)或Mongoose庫(kù)來(lái)連接和操作MongoDB數(shù)據(jù)庫(kù),本文就來(lái)介紹一下Node.js中MongoDB插入數(shù)據(jù)的實(shí)現(xiàn)方法,感興趣的可以了解一下2023-12-12Nodejs封裝類似express框架的路由實(shí)例詳解
在本篇文章里小編給大家整理的是關(guān)于Nodejs封裝類似express框架的路由實(shí)例內(nèi)容,有需要的朋友們學(xué)習(xí)下。2020-01-01