AJAX大文件切割上传(带进度条)

时间:2022-10-07 15:24:43

依旧要用到HTML5新出的API.

通过file对象
file-->继承自-->Blob
Blob有slice方法,可以截取二进制对象的一部分.

 

前言:  由于JS无法操作文件内容使AJAX无法上传文件,但在新的HTML5中通过FILE文件对象,就可以获得文件内容.使AJAX真正的实现了上传文件.

         file对象-->继承自-->Blob二进制对象 . Blob有slice方法,可以截取二进制对象的一部分. 下面将用silce方法进行文件切割.

 

实现思路及步骤:

           1  通过files对象获取到文件.

           2  利用slice方法切割.

           3  上传切割出的部分文件

           4  PHP将每次接收到的文件进行拼接.

           5  重复切割上传,直到文件全部上传完成

         

  1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  3 <head>
  4     <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
  5     <title>Document</title>
  6 </head>
  7 <script type="text/javascript"> 
  8     function sub(){
  9        ajax_upload = setInterval(upload,1000);
 10     }
 11     
 12     //AJAX上传(闭包原理)
 13     var upload = (function(){
 14         //步长
 15         var step = 10*1024*1024;
 16         //切割起点
 17         var begin = 0;
 18         //切割结束点
 19         var end = begin + step;
 20         //上传文件的file对象
 21         var upfile = null;
 22         //文件总大小
 23         var size = 0;
 24         //数据对象
 25         var data = null;
 26         //分割的文件
 27         var blob = null;
 28         //XML对象
 29         var xhr = null;
 30         //允许下个blob上传
 31         var go  = true;
 32         //进度
 33         var progress = 0;
 34         
 35         return function(){
 36             if(go == false) return;
 37             go = false;
 38             //上传文件的file对象
 39             upfile = document.getElementsByTagName('input')[0].files[0];
 40             //文件总大小
 41             size = upfile.size;
 42             //当起始点超过文件总大小,退出上传.
 43             if(begin > size){
 44                 clearInterval(ajax_upload);
 45                 //切割起点
 46                 begin = 0;
 47                 //切割结束点
 48                 end = begin + step;
 49                 //允许下个blob上传
 50                 go  = true;
 51                 //进度
 52                 progress = 0;
 53                return;  
 54             } 
 55             //XML对象
 56             xhr = new XMLHttpRequest();
 57             //建立连接
 58             xhr.open('POST','1.php',false);
 59             //分割文件
 60  blob = upfile.slice(begin,end);  61             //数据对象
 62             data = new FormData();
 63             data.append('files',blob);
 64             //发送
 65             xhr.send(data);
 66             //更新进度条
 67             progress = (end/size)*100;
 68             if(progress > 100) progress = 100;
 69             pg_bar = document.getElementsByTagName('div')[1];
 70             pg_bar.style.width = progress + '%';
 71             pg_num = document.getElementsByTagName('span')[0];
 72             pg_num.innerHTML = parseInt(progress)+ '%';
 73             //计算下次切割点
 74             begin = end ;
 75             end   = begin + step ;
 76             //允许下个blob上传
 77             go = true; 
 78         }
 79     })();
 80     
 81 </script>
 82 <style>
 83    .loaded_box{
 84       margin-top: 10px;
 85       width: 200px;
 86       height: 8px;
 87       border: 1px solid lightblue;
 88    }
 89    .loaded{
 90       width: 0%;
 91       height: 8px;
 92       background: lightblue;
 93    }
 94 </style>
 95 <body>
 96  
 97         上传文件 <input type="file" name="file"/>
 98         <br />
 99         <input type="submit" value="上传" name="file" onclick="return sub()"/>
100         
101         <div class="loaded_box">
102             <div class="loaded"></div>
103             <span>0%</span>
104         </div>
105 </body>
106 </html>

PHP代码

1 if(!file_exists('./hhr.mov')) {  //由于是举例测试,所以没做充分的判断.你上传的文件也并非叫hhr.mov .自行修改做测试.
2     move_uploaded_file($_FILES['part']['tmp_name'],'./upload/hhr.mov');
3 } else {
4     file_put_contents('./upload/hhr.mov',file_get_contents($_FILES['part']['tmp_name']),FILE_APPEND);
5 }

思路: 如果当前接收到的文件已经存在.那么将认为改文件是已存在文件的一部分.那么将接收到的文件内容通过file_put_content函数追加进去
如果当前接收到的文件不存在,则用move_uploaded_file正常上传.

 

效果

AJAX大文件切割上传(带进度条)