您的位置:首页 > Web前端 > JavaScript

FireFox浏览器使用Javascript上传大文件

2013-10-30 15:33 567 查看
<!DOCTYPE HTML>  2  <html>  3  <head>  4  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  5  <title>FireFoxFileSender - !! ONLY FOR FireFox !!</title>  6  </head>  7   8  <body>  9  <script type="text/Javascript"> 10  /* 11  * FireFoxFileSender version 0.0.0.1 12  * by MK winnie_mk(a)126.com 13  *  14  * 【本程序仅限于FireFox3.x版本,其他浏览器是否可以运行未做测试。】 15  * 【测试通过:FireFox 3.6.8 / Apache/2.2.11 (Win32) PHP/5.2.6 】 16  * ********************************************************************************* 17  * 本程序是利用3.x的FireFox浏览器可以读取本地文件的特性 18  * 实现通过XMLHttpRequest上传大文件功能 19  * 并在可以上传过程中动态显示上传进度 20  * 略加修改,并与服务器端配合,可以实现断点续传等诸多功能 21  * 本例主要是研究FireFox的file-input节点的一些特性 22  * 其他客户端应用,如Flash、Sliverlight等,在实现客户端大文件上传时 23  * 在数据传输与服务器端存储等方面,与本例的思路基本一致 24  * 注意:文件体积似乎有个临界点,但这个临界点是多少尚未确认。建议不要用此方法上传超过100M的文件。 25  * ********************************************************************************* 26  */ 27  function FireFoxFileSender(config){ 28     var conf = config || {}; 29     /* 30      * 错误信息队列 31      */ 32     this.errMsg = [];     33     /* 34      * 判断各参数是否齐备 35      */ 36     this.f = typeof conf.file == 'string' ? document.getElementById(conf.file) : conf.file; 37     if(!this.f){ this.errMsg.push('Error: Not set the input file.'); } 38     else if(this.f.files.length < 1){ this.errMsg.push('Error: Not select a file.'); } 39     else { 40         this.fileName = this.f.value; 41         /* 42          * 在尝试直接发送二进制流时失败,改用发送base64编码数据。 43          */ 44         this.data = (this.data = this.f.files[0].getAsDataURL()).substr(this.data.indexOf(',') + 1); 45         this.length = this.data.length; 46         /* 47          * 文件实际大小 48          */ 49         this.fileSize = this.f.files[0].fileSize; 50         /* 51          * 文件类型 52          */ 53         this.contentType = this.f.files[0].fileType; 54     } 55     /* 56      * 服务器端接收地址 57      */ 58     this.url = conf.url; 59     if(!this.url){ this.errMsg.push('Error: Not set the instance url to send binary.'); } 60     /* 61      * 发送数据包的大小。默认100kb 62      */ 63     this.packageSize = conf.packageSize || 102400; 64     /* 65      * 每次发送数据包大小应为4的倍数,确保服务器端转换base64编码正确。 66      */ 67     if(this.packageSize % 4 != 0) this.packageSize = parseInt(this.packageSize / 4) * 4; 68      69     this.onSendFinished = conf.onSendFinished || null; 70     this.onSending = conf.onSending || null; 71     this.onError = conf.onError || null; 72 } 73 FireFoxFileSender.prototype = { 74     /* 75      * 记录当前发送的数据 76      */ 77     currentData : null, 78     /* 79      * 记录读取位置 80      */ 81     position : 0, 82     /* 83      * 数据大小。该值为base64字符串的长度。 84      */ 85     length : -1, 86     /* 87      * 检查错误队列,尝试触发onError事件 88      */ 89     checkError : function(){ 90         if(this.errMsg.length > 0){ 91             /*  92              * 触发onError事件 93              */ 94             typeof this.onError == 'function' && this.onError(this.errMsg); 95             return; 96         } 97     }, 98     /* 99      * 创建XMLHttpRequest100      */101     createSender : function(){102         var xhr = new XMLHttpRequest();103         xhr.open('POST', this.url, true);104         var _ = this;105         xhr.onreadystatechange = function(){106             /*107              * 当服务器段响应正常,则循环读取发送。108              */109             if(xhr.readyState == 4 && xhr.status == 200){110                 /* 111                  * 触发onSending事件112                  */113                 if(typeof _.onSending == 'function') _.onSending(_, xhr);114                 /*115                  * 延时发送下一次请求,否则服务器负担过重116                  */117                 var send = setTimeout(function(){118                     _.send();119                     clearTimeout(send);120                     send = null;121                 }, 100);                122             }123         }124         return xhr;125     },126     /*127      * 发送数据128      */129     send : function(){130         this.checkError();131         /*132          * 获取当前要发送的数据133          */134         this.currentData = this.data.substr(this.position, this.packageSize);135         /*136          * 更改postion,模拟数据流移位137          */138         this.position += this.currentData.length;139         /*140          * 如果读取字符串长度大于0,则发送该数据141          * 否则触发onSendFinished事件142          */143         if(this.currentData.length > 0) {144             var xhr = this.createSender();145             /*146              * 自定义头部信息,通知服务器端文件相关信息147              * 实际应用时可修改此部分。148              */149             xhr.setRequestHeader('#FILE_NAME#', this.fileName);150             xhr.setRequestHeader('#FILE_SIZE#', this.length);151             xhr.setRequestHeader('#CONTENT_TYPE#', this.contentType);152             153             xhr.send(this.currentData);154         } else if(typeof this.onSendFinished == 'function') {155             /*156              * 触发onSendFinished事件157              */158             this.onSendFinished(this);159         }160     },161     /*162      * 计算已发送数据百分比163      */164     percent : function(){165         if(this.length <= 0 ) return -1;166         return Math.round((this.position / this.length) * 10000) / 100;167     },168     onSendFinished : null,    //该事件是以本地数据发送完成为触发,并不是服务器端返回的完成信息。169      onSending : null,170     onError : null171 }172 173  /*174  * 上传按钮事件175  */176  function%3
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息