也说文件上传之兼容IE789的进度条---丢掉flash
最近在整理前端常用到的一些组件,像分页(get/post两类)、下拉框(下拉单选/下拉多选/省市区联动)、模态框等;当然还有文件上传啦,如果只考虑用HTML5的话,前端方面的工作,那家伙老简单了,分分钟搞定,不就是验证,显示文件信息,加个进度条,回调下么;好吧,说得简单而已,自己动手完整的实现一遍试试;对于PC端的前端而言,大多时候可能还得顾及一下IE7+;那么问题就来了,IE789都不支持H5的file API,so,让我们一起BSIE吧!
上传显示文件类型、大小、文件名,这些百度立马出结果,不多说了;
至于在IE789上显示进度条,这个就得自己琢磨了,如果你的工作用过上传图片或上传大文件啥的,一般在IE低版本浏览器里,会切换到用flash解决;包括牛逼哄哄的百度WebUploader;话说,既然我想自己实现一遍,我肯定不会为了老旧IE的进度条而去学flash;因为在我心里,H5早已秒了flash;那么,自己挖坑就只能自己填咯!
先简单看看Nodejs对文件上传的处理吧!在Express4里req.files已经是undefined了;现在用的最多的可能就是formidable了;github到formidable,你知道了它有个progress事件,于是心中大喜,低版本IE的进度条有戏了;OK,试一下:
1 form
2 .on('error',function(err){
3 console.log(err);
4 })
5 .on('aborted',function(){
6 console.log('aborted');
7 })
8 .on('progress',function(bytesReceived, bytesExpected){
9 var n=parseInt(parseFloat(bytesReceived/bytesExpected).toFixed(2)*100);
10 console.log(n);
11 });
是的,你很高兴的看到了,控制台按照预期打印了一串进度值;那么,再进一步;
1 form
2 .on('progress',function(bytesReceived, bytesExpected){
3 var n=parseInt(parseFloat(bytesReceived/bytesExpected).toFixed(2)*100);
4 res.write('<script>window.parent.call('+n+')</script>');
5 //无刷新上传,你们懂的
6 console.log(n);
7 });
call方法即在页面上显示进度值;很不幸,你只能看到最后的100%,看不到上传具体详细的进度值;再探...
接下来换个思路,试一下,将进度值保存到session里,额外加一个请求来轮询这个进度值,哎哟,不错哦!为了保证你请求的进度值是你这次上传的进度值而不是其他上传的进度值,需要在上传的请求里和额外的请求里约定一个token值;现在又来一个问题就是怎么在请求的时候得到这个token,由于文件上传的请求体在Request Payload里,所以req.body拿不到带过去的值,我也不想去解析这堆了,当然我也解析不了;放在url里最好,问题在于有时候得刷新两次来刷新token,不好!不得已,我还是放在cookie里吧!
1 var cookies=function () {
2 var cks=req.headers.cookie.split(';'),obj={};
3 for(var i=0;i<cks.length;i++){
4 obj[cks[i].split('=')[0].replace(/\s+/ig,'')]=unescape(cks[i].split('=')[1]);
5 }
6 return obj;
7 }();
8 var queryToken=cookies.__token__;
9
10 form
11 .on('progress',function(bytesReceived, bytesExpected){
12 var n=parseInt(parseFloat(form.bytesReceived/form.bytesExpected).toFixed(2)*100);
13 if (req.session['file'+queryToken]) {
14 req.session['file'+queryToken].percent=n;
15 }else{
16 req.session['file'+queryToken]={
17 token:queryToken,
18 percent:n
19 }
20 };
21 console.log(n);
22 });
为了IE789,我来轮询进度值了,原谅我,其实我的心很痛;
1 var getData=function(){
2 $.post('/uploader',{
3 getfileinfo:1,
4 uploadtoken:utils.cookie.getCookie('__token__')
5 }).then(function(data){
6 console.log(data);
7 if (data.mes<0) {
8 getData();
9 }else{
10 var pros=data.info;
11 call(pros.percent);
12 if (pros.percent!='100') {
13 getData();
14 };
15 };
16 });
17 }
18 getData();
call方法即在页面上显示进度值;很不幸,你只能看到最后的100%,看不到上传具体详细的进度值;再探...
好吧,我又一次沦陷了;不过还是感觉不对劲,ajax轮询没有问题,问题在于session里要等到上传完毕才有值,所以只能看到100%,看不到详细进度值;我是否可以认为,在progress里,之前的res.write和这次的req.session被挂起了呢,但是它又保存了每次的执行结果,直到progress完再释放,所以只能看到100%;没心情看formidable的源码,当然我也看不咋懂,我就先这么认为吧!
既然ajax轮询没问题,那么就是保存到session不得劲了;实在不成,放到global里试试吧,总不会往全局对象里塞个值也会挂起吧;稍作改动放到global里:
1 form
2 .on('progress',function(bytesReceived, bytesExpected){
3 var n=parseInt(parseFloat(form.bytesReceived/form.bytesExpected).toFixed(2)*100);
4 if (global['file'+queryToken]) {
5 global['file'+queryToken].percent=n;
6 }else{
7 global['file'+queryToken]={
8 token:queryToken,
9 percent:n
10 }
11 };
12 console.log(n);
13 });
继续轮询。
漂亮,完全就是那么回事!在chrome里看到的和HTML5的进度一个效果,只是在IE789里会有点卡顿的感觉,不过还是能看到详细的进度值的;毕竟老浏览器身子骨不咋地,你们懂的;还有,每次上传都往global里塞值,怎么也得适当的清理一下吧,文件上传完毕,转移到指定目录后global['file'+queryToken]=null;
然而,轮询,就是一个接一个好多好多的请求,这里也许会出问题;要不限制一下吧,间隔500ms请求一次进度值;恩,IE789进度条就这么解决了,说好的丢掉flash;虽然这个轮询可以兼容所有浏览器,但毕竟要浪费那么多请求,还是判断下,在IE789以外继续HTML5吧!
其实衡量一下,额外加个flash上传和额外的请求,哪个更值呢,原谅我不懂flash,就不多说了,反正我很不喜欢在页面上加一下额外的文件;
关于文件上传的组件,还有很多的细节处理,本想弄一个JS文件的,后来一想,为了可复用性更强,还是作为一个独立的页面搞比较好,需要上传的地方,iframe一下就行了,肯定比弄一个JS文件要好很多;更多细节内容,持续整理中,不敢和网上成型的上传比,仅当自己前端路上的积累和实践,我感觉可以用的话,就和大家分享了,与君共勉!
如若转载,请注明出处:sau交流学习社区-power by saucxs(程新松)(/page/180.html)
- 记录一次nginx故障:recv() failed (104: Connection reset by peer) while reading response header from upstream,
- 微信小程序初体验,入门练手项目--通讯录,部署上线(二)
- 微信小程序初体验,入门练手项目--通讯录,后台是阿里云服务器(一)
- thinkjs性能优化之nginx配置
- 开学AI登场!南京高校用人脸识别查考勤管理学生,还敢逃课、玩手机?姚AI变脸热到爆!开源换脸工具FakeSwap今登GitHub排行榜第二位,ICLR飞升,IJCAI降级:清华的新版AI顶会评级引发学术圈热议,意外!已获6700万美元投资的自动驾驶LiDAR创业公司关门了
标签云
图文推荐
“深度学习”这十年:52篇大神级论文再现AI荣与光,12岁上大学、31岁成最年轻IEEE Fellow,前百度总裁张亚勤加盟清华,全球女性福音!DeepHealth深度学习模型检测乳腺癌完胜5名放射科医师,读博无门,就业碰壁,孤独当了7个月“民科”后,我的论文中了顶会Spotlight
saucxs 2020-01-03 10:04:09
1200 万部手机、500 亿实时位置数据,上帝视角还原特朗普全天行踪,自动驾驶玩漂移 斯坦福最新研究:《头文字D》无人车版来了,印度裔又要统领美国科学界?特朗普提名他领导美国国家科学基金会,GitHub排名第一!免费最强“抢票神器”在手,程序员抢票再不用跪求加速包
saucxs 2019-12-25 10:08:05
蝉联AI专业全球冠军!清华力压CMU再夺CSRankings高校AI排行王座,波士顿动力CEO:不排斥军方订单,就想你粗暴地对待机器狗,亚马逊Alexa突然发疯,读着论文教主人自杀:你活着地球人口会过剩,图神经网络的ImageNet?斯坦福大学等开源百万量级OGB基准测试数据集
saucxs 2019-12-24 09:57:45
2020 AAAI Fellow名单出炉!深度学习先驱Bengio和LeCun双双入选,李世石最后一战不敌AI“韩豆”!唯一战胜过AlphaGo的男人正式退役,GAN和PS合体会怎样?东京大学图像增强新研究:无需配对图像,增强效果还可解释,2019年最受关注的100项研究,AI“复活”蒙娜丽莎排第一
saucxs 2019-12-23 09:58:10
这家AI公司用面具破解中国人脸识别系统!微信、支付宝、火车站无一幸免,OpenAI公开Dota 2论文:胜率99.4%,「手术」工具连续迁移训练,9岁神童大学毕业前突然退学,转赴美国攻读电气工程博士,Reddit热议:15岁高中生用神经网络建立生命进化“新宇宙”
saucxs 2019-12-17 09:45:30
- 东方财富
- saucxs博客园
- weekly周报
- loveBook
- 前端博客
- 技术交流学习社区
- saucxs
- segmentfault
- saucxs的博客
- haorooms
- luckyscript
- 东方财富期货
- 峰云就她了
- binlive
- songEagle
- 且听风吟
- (TX)Heying Ye
- CG Online Judge
- Chris's Blog
- vueRouter
- 龙恩0707
- 鑫空间,鑫生活
- 木易杨
- MDN-js
- Cherry's Blog
- InterviewMap
- 安安哥的小戏台
- xiaojun1994-cat
- JavaScript-Garden
- junruchen-daily
- 秋天爱美丽
- web-summary-daily
- w3cplus-tb
- 潜行者m
- 于江水
- KieSun-git
- cnodejs
- aerminBlog
- fex_bd
- gwuhaolin-git
- Deboy's Blog
- react-china
- react.docschina
- Vuejs社区
- vuejsDoc
- cdnSocketIo
- shuaihuaCC
- colorize
- stazhu
- 前端学习
- IBM Dev社区
- linux运维笔记
- webpackDoc
- sayskyGithub
- 前端里
- 996.ICU
- electronjs
- CS-Notes
- mqyqingfengBlog
- beego官方
- 编码规范
- 阮一峰个人网站
- sessionstack
- damonareGoUp
- 咀嚼之味
- fe-interview
- xd-tayde/blog
- css-tricks
- ghmagical个人中心
- markyunp6
- hellogithub
- 霜序廿
- rin部落
- 建站素材
- 前端资源网
- CSS开发手册
- web技术交流
- 程新松个人网站
- wangEditor
- 小松博客
- 交流学习社区