0
点赞
收藏
分享

微信扫一扫

Ajax实现大文件切割上传

杨小羊_ba17 2022-03-30 阅读 96


Ajax大文件切割上传

2015-02-07


前面我们已经实现了Ajax的文件上传,不过会受限于服务器的允许的大小,

如果服务器并非自己的,我们就要使用Ajax大文件切割来实现上传。


首先解决Ajax跨域上传问题:

在HTML5中,ajax的跨域有了新的规则-----能否跨域取决于对应的应答。

对方服务器如果愿意接受远程过来的ajax,或某几个域名过来的ajax请求,可以在头信息header中,加入Access-Control-Allow-Origin *

在PHP中加入此信息,就可以实现跨域请求。


一、简陋的文件时上传思路

截取用到的API

     file->继承自->Blob

     Blob有slice方法,可以截取二进制对象的一部分

     思路:截取10M,上传

     判断文件有没有截取完毕

     while 还有数据{

         截取

        上传

     }

Ajax实现大文件切割上传_上传

html文件代码:


1 <html>
2 <head>
3 <title>FormData</title>
4 <script type="text/javascript">
5 */
6 /*用到的API
7 file->继承自->Blob
8 Blob有slice方法,可以截取二进制对象的一部分
9 思路:截取10M,上传
10 判断文件有没有截取完毕
11 while 还有数据{
12 截取
13 上传
14 }
15
16 */
17 function selectfile(){
18 const LENGTH = 10 * 1024 * 1024; //每次截取的长度
19 var sta = 0; //从零处开始截取
20 var end = sta +LENGTH;
21 var blob = null;
22 var fd = null;
23 var xhr = null;
24 var percent = 0;
25
26 /* blob对象 */
27 var mov = document.getElementsByTagName('input')[0].files[0];
28 var totalsize = mov.size;
29
30
31 while(sta < totalsize){
32 blob = mov.slice(sta,end);
33 fd = new FormData(); //定义一个FormData数组
34 fd.append('part',blob);//格式化
35
36 xhr = new XMLHttpRequest();
37   //post发送
38   xhr.open('POST','HTML5upJinDuTiao_DaWenJianShangchuan.php',false);
39
40 xhr.onreadystatechange = function(){
41 if(this.readyState == 4){
42 document.getElementById('debug').innerHTML = this.responseText;
43 }
44 }
45 console.log(blob);
46
47 xhr.send(fd);
48 sta = end;
49 end +=LENGTH;
50 }
51 }
52
53 </script>
54
55 <style type='text/css'>
56 img{ width:500px; }
57 #progress{width:500px; height:15px; border:1px solid green;}
58 #bar{width:0%; height:100%; background:green;}
59 </style>
60
61
62 </head>
63 <body>
64 <h1>ajax大文件切割上传</h1>
65 <input type="file" name="pic" onchange="selectfile();" />
66 <hr/>
67 <div id="progress">
68 <div id="bar"></div>
69 </div>
70 <div id="debug2"></div>
71 <hr/>
72 <div id="debug"></div>
73
74
75 </body>
76 </html>
77


php文件代码:


1 <?php
2
3 /*接收文件并合并*/
4
5 print_r($_FILES);
6
7 if(!file_exists('./upload/up.mp4')){
8 move_uploaded_file($_FILES['part']['tmp_name'],'./upload/up.mp4');
9 }else{
10 file_put_contents('./upload/up.mp4',file_get_contents('./upload/up.mp4').file_get_contents($_FILES['part']['tmp_name']));
11 }
12
13 echo 'ok';
14
15 ?>



这个是一个简陋的大文件切割上传程序,如果想看进度,或者查看其是否再上传,我们必须按下F12,在控制台中看,文件没切割一次,相应的信息就会在控制台中显示一行。

Ajax实现大文件切割上传_上传_02



二、改进(增加上传进度条)

由于浏览器对页面渲染的优化,如果要增加上传进度条显示的话,经过浏览器的渲染优化,我们的进度条在上传是不会增加,而是在上传完毕后,直接从0增加对100,这个是无法忍受的。

原因是:浏览器渲染的优化,​reflow,​具体可以网上找相应的详细资料。

为了增加进度条效果,我们可以使用window的定时器,

clock = window.setInterval(selectfile,1000);

让它每秒钟刷新一下页面,计算当前上传进度,显示出来。


html文件代码:


1 <html>
2 <head>
3 <title>FormData</title>
4 <script type="text/javascript">
5
6 /*用到的API
7 file->继承自->Blob
8 Blob有slice方法,可以截取二进制对象的一部分
9 思路:截取10M,上传
10 判断文件有没有截取完毕
11 利用定时器不断的调用
12 */
13 xhr = new XMLHttpRequest();
14 var clock = null;
15
16 //file选择,触发定时器函数
17 function selectfile_fire(){
18 clock = window.setInterval(selectfile,1000);
19 //定时1s
20 }
21
22 //闭包函数
23 var selectfile = (function(){
24 const LENGTH = 10*1024*1024;//每次截取的长度
25 var sta = 0; //从零处开始截取
26 var end = sta +LENGTH;
27 var flag = false; //表示上一块是否发送完毕
28 var blob = null;
29 var fd = null;
30 var percent = 0;
31
32 //匿名函数
33 return(function (){
34 alert("aa");
35 if(flag == true){    //是否正在上传
36 return;
37 }
38 flag = true;
39 var mov = document.getElementsByTagName('input')[0].files[0];/* blob对象 */
40
41 fd = new FormData();
42 blob = mov.slice(sta,end);
43 fd.append('part',blob);
44 up(fd);
45
46 //如果sta > mov.size 就结束
47 if(sta >= mov.size){
48 clearInterval(clock); //清除定时
49 return ;
50 }
51 sta = end;
52 end = sta + LENGTH;
53 flag = false; //上传完毕
54
55 percent = 100 * end /mov.size ;
56 percent = percent >= 100 ? 100 : percent;
57 document.getElementById('bar').style.width = percent + "%";
58 document.getElementById('bar').innerHTML = parseInt(percent) + "%" ;
59
60 });
61 })();
62
63 /*利用定时器不断调用*/
64 function up(fd){
65 xhr.open('POST','HTML5upJinDuTiao_DaWenJianShangchuan.php',false); //post发送
66 xhr.send(fd);
67 }
68
69
70 </script>
71
72 <style type='text/css'>
73 img{ width:500px; }
74 #progress{width:500px; height:15px; border:1px solid green;}
75 #bar{width:0%; height:100%; background:green;}
76 </style>
77
78
79 </head>
80 <body>
81 <h1>ajax大文件切割上传</h1>
82 <input type="file" name="pic" onchange="selectfile_fire();" />
83 <hr/>
84 <div id="progress">
85 <div id="bar"></div>
86 </div>
87 <div id="debug2"></div>
88 <hr/>
89 <div id="debug"></div>
90
91
92 </body>
93 </html>




php文件代码:


1 <?php
2
3 /*接收文件并合并*/
4
5 print_r($_FILES);
6
7 if(!file_exists('./upload/up.mp4')){
8 move_uploaded_file($_FILES['part']['tmp_name'],'./upload/up.mp4');
9 }else{
10 file_put_contents('./upload/up.mp4',file_get_contents('./upload/up.mp4').file_get_contents($_FILES['part']['tmp_name']));
11 }
12
13 echo 'ok';
14
15 ?>


Ajax实现大文件切割上传_上传_03Ajax实现大文件切割上传_上传_04



举报

相关推荐

0 条评论