这里有新鲜出炉的 Node.js 教程,程序狗速度看过来!
Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台, 用来方便地搭建快速的 易于扩展的网络应用 · Node.js 借助事件驱动, 非阻塞 I/O 模型变得轻量和高效, 非常适合 运行在分布式设备 的 数据密集型 的实时应用
这篇文章给大家介绍了如何实现兼容 IE789 的文件上传进度条,如果你的工作用过上传图片或上传大文件啥的,一般在 IE 低版本浏览器里,会切换到用 flash 解决, 可是有些人肯定不会为了老旧 IE 的进度条而去学 flash,那么下面来一起看看吧。
Nodejs 对文件上传的处理
在 Express4 里 req.files 已经是
了;现在用的最多的可能就是
- undefined
了,你知道了它有个
- formidable
事件,于是心中大喜,低版本 IE 的进度条有戏了;OK,试一下:
- progress
- 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);
- });
是的,你很高兴的看到了,控制台按照预期打印了一串进度值;那么,再进一步;
- form
- .on('progress',function(bytesReceived, bytesExpected){
- var n=parseInt(parseFloat(bytesReceived/bytesExpected).toFixed(2)*100);
- res.write('<script>window.parent.call('+n+')</script>');
- //无刷新上传,你们懂的 console.log(n);
- });
方法即在页面上显示进度值;很不幸,你只能看到最后的 100%,看不到上传具体详细的进度值;再探...
- call
接下来换个思路,试一下,将进度值保存到
里,额外加一个请求来轮询这个进度值,哎哟,不错哦!为了保证你请求的进度值是你这次上传的进度值而不是其他上传的进度值,需要在上传的请求里和额外的请求里约定一个
- session
值;现在又来一个问题就是怎么在请求的时候得到这个
- token
,由于文件上传的请求体在
- token
里,所以
- Request Payload
拿不到带过去的值,我也不想去解析这堆了,当然我也解析不了;放在
- req.body
里最好,问题在于有时候得刷新两次来刷新
- url
,不好!不得已,我还是放在
- 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,我来轮询进度值了,原谅我,其实我的心很痛;
- 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();
方法即在页面上显示进度值;很不幸,你只能看到最后的 100%,看不到上传具体详细的进度值;再探...
- call
好吧,我又一次沦陷了;不过还是感觉不对劲,ajax 轮询没有问题,问题在于
里要等到上传完毕才有值,所以只能看到 100%,看不到详细进度值;我是否可以认为,在 progress 里,之前的
- session
和这次的
- res.write
被挂起了呢,但是它又保存了每次的执行结果,直到
- req.session
完再释放,所以只能看到 100%;没心情看
- progress
的源码,当然我也看不咋懂,我就先这么认为吧!
- formidable
既然
轮询没问题,那么就是保存到
- ajax
不得劲了;实在不成,放到
- session
里试试吧,总不会往全局对象里塞个值也会挂起吧;稍作改动放到
- global
里:
- 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);
- });
继续轮询。
漂亮,完全就是那么回事!在 chrome 里看到的和 html5 的进度一个效果,只是在 IE789 里会有点卡顿的感觉,不过还是能看到详细的进度值的;毕竟老浏览器身子骨不咋地,你们懂的;还有,每次上传都往
里塞值,怎么也得适当的清理一下吧,文件上传完毕,转移到指定目录后
- global
;
- global['file'+queryToken]=null
然而,轮询,就是一个接一个好多好多的请求,这里也许会出问题;要不限制一下吧,间隔 500ms 请求一次进度值;恩,IE789 进度条就这么解决了,说好的丢掉 flash;虽然这个轮询可以兼容所有浏览器,但毕竟要浪费那么多请求,还是判断下,在 IE789 以外继续 HTML5 吧!
其实衡量一下,额外加个 flash 上传和额外的请求,哪个更值呢,原谅我不懂 flash,就不多说了,反正我很不喜欢在页面上加一下额外的文件;
总结
关于文件上传的组件,还有很多的细节处理,本想弄一个 JS 文件的,后来一想,为了可复用性更强,还是作为一个独立的页面搞比较好,需要上传的地方,iframe 一下就行了,肯定比弄一个 JS 文件要好很多。以上就是这篇文章的全部内容,希望能够对大家的学习或者工作带来一定的帮助,如果有疑问大家可以留言交流。
来源: http://www.phperz.com/article/17/0502/332145.html