首页 新闻 会员 周边 捐助

FileReader分段读取并上传有问题?

0
悬赏园豆:30 [已关闭问题] 关闭于 2013-12-02 15:50

要实现的功能是前台用html5文件api读取要上传的文件,用ajax请求把读取的内容上传到php服务端处理,但是如果文件太大就会导致浏览器崩溃(用的是chrome最新版),所以在前端就用File.slice把文件分块,并在服务端用php合并为完整的文件。

前端javascript如下:

 1 <style>
 2 #container {
 3         min-width:300px;
 4         min-height:200px;
 5         border:3px dashed #000;
 6 }
 7 </style>
 8 <div id='container'>
 9         
10 </div>
11 <script>
12 function addDNDListener(obj){
13         obj.addEventListener('dragover',function(e){
14                 e.preventDefault();
15                 e.stopPropagation();
16         },false);
17         obj.addEventListener('dragenter',function(e){
18                 e.preventDefault();
19                 e.stopPropagation();
20         },false);
21         obj.addEventListener('drop',function(e){
22                 e.preventDefault();
23                 e.stopPropagation();
24                 var ul = document.createElement("ul");
25                 var filelist = e.dataTransfer.files;
26                 for(var i=0;i<filelist.length;i++){
27                         var file = filelist[i];
28                         var li = document.createElement('li');
29                         li.innerHTML = '<label id="'+file.name+'">'+file.name+':</label><progress value="0" max="100"></progress>';
30                         ul.appendChild(li);
31                 }
32                 document.getElementById('container').appendChild(ul);
33                 for(var i=0;i<filelist.length;i++){
34                         var file = filelist[i];
35                         uploadFile(file);
36                 }
37         },false);
38 }
39 
40 function uploadFile(file){
41         var loaded = 0;
42         var step = 1024*1024;
43         var total = file.size;
44         var start = 0;
45         var progress = document.getElementById(file.name).nextSibling;
46         
47         var reader = new FileReader();
48 
49         reader.onprogress = function(e){
50                 loaded += e.loaded;
51                 progress.value = (loaded/total) * 100;
52         };
53 
54         reader.onload = function(e){
55                 var xhr = new XMLHttpRequest();
56                 var upload = xhr.upload;
57                 upload.addEventListener('load',function(){
58                         if(loaded <= total){
59                                 blob = file.slice(loaded,loaded+step+1);
60                                 reader.readAsBinaryString(blob);
61                         }else{
62                                 loaded = total;
63                         }
64                 },false);
65                 xhr.open("POST", "upload.php?fileName="+file.name+"&nocache="+new Date().getTime());
66                 xhr.overrideMimeType("application/octet-stream");
67                 xhr.sendAsBinary(e.target.result);
68         };
69         var blob = file.slice(start,start+step+1);
70         reader.readAsBinaryString(blob);
71 }
72 
73 window.onload = function(){
74         
75         addDNDListener(document.getElementById('container'));
76         if(!XMLHttpRequest.prototype.sendAsBinary){ 
77                   XMLHttpRequest.prototype.sendAsBinary = function(datastr) {  
78                             function byteValue(x) {  
79                                 return x.charCodeAt(0) & 0xff;  
80                             }  
81                             var ords = Array.prototype.map.call(datastr, byteValue);  
82                             var ui8a = new Uint8Array(ords);  
83                             try{
84                                 this.send(ui8a);
85                             }catch(e){
86                                 this.send(ui8a.buffer);
87                             }  
88                   };  
89         }
90 };
91 </script>

后台php代码如下:

 1 <?php
 2         $filename = "upload/".$_GET['fileName'];
 3         //$filename = "upload/".$_GET['fileName']."_".$_GET['nocache'];
 4         $xmlstr = $GLOBALS['HTTP_RAW_POST_DATA'];
 5         if(empty($xmlstr)){
 6                 $xmlstr = file_get_contents('php://input');
 7         }
 8         $is_ok = false;
 9         while(!$is_ok){
10                 $file = fopen($filename,"ab");
11         
12                 if(flock($file,LOCK_EX)){
13                         fwrite($file,$xmlstr);
14                         flock($file,LOCK_UN);
15                         fclose($file);
16                         $is_ok = true;
17                 }else{
18                         fclose($file);
19                         sleep(3);
20                 }
21         }

问题就是每次上传完之后文件大小总是比原始大小小一点,可能是最后一段没有上传到服务器,导致文件不完整(现在每次分片的大小是1M,小于2M的文件没问题,超过就有问题),求教问题出在哪里?还有我觉得现在这些代码质量,代码风格也有点问题,哪些地方是可以改进的?3QVM~~

sangelee的主页 sangelee | 初学一级 | 园豆:174
提问于:2013-11-15 16:54
< >
分享
所有回答(1)
0

文件也可以用ajax传了?

angelshelter | 园豆:9914 (大侠五级) | 2013-11-18 17:45

恩,用html5的文件api

支持(0) 反对(0) sangelee | 园豆:174 (初学一级) | 2013-11-19 08:54

@sangelee: 请问如何解决的

支持(1) 反对(0) 王者杂货铺 | 园豆:204 (菜鸟二级) | 2015-05-07 09:44
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册