最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

tp5+layui实现上传大文件介绍

来源:动视网 责编:小采 时间:2020-11-03 18:22:41
文档

tp5+layui实现上传大文件介绍

tp5+layui实现上传大文件介绍:首先记录下更改文件上传大小的一些配置信息.打开php.inifile_uploads = on //是否允许通过HTTP上传文件的开关,默认开启upload_tmp_dir //临时文件储存的路径upload_max_filesize 20M //允许上传的文件最大值post_max_size 22M //通
推荐度:
导读tp5+layui实现上传大文件介绍:首先记录下更改文件上传大小的一些配置信息.打开php.inifile_uploads = on //是否允许通过HTTP上传文件的开关,默认开启upload_tmp_dir //临时文件储存的路径upload_max_filesize 20M //允许上传的文件最大值post_max_size 22M //通


通过更改上述的配置就可以调整允许文件上传的大小。(有的还需要调整服务器的一些配置)

补充:413错误 如果服务器是nginx的话,需要更改配置nginx_conf 中的client_max_body_size 24M,设置接收客户端发送过来包的最大值。记得放在http里,重启服务器,用restart,不要用reload。

接着开始实现文件的分割上传。

文件通过HTML的input标签的file来选择文件上传。通过H5新对象FileReader。就像字面上的意思一样FileRaeder对象就是一个读取本地文件的对象。FileReader对象可以将本地文件读取后以base位的编码返回。(具体有关FileReader对象的使用,请自行百度,或者阅读以下博文,写的很具体。

实际开发

第一次尝试

通过input file标签来选择文件

采用FileReader对象对文件进行读取

通过ajax异步将文件的base编码发送给服务端

服务端接收后对编码进行解码并保存到文件中。

测试结果失败,当文件过大时所编码的长度也越长,通过ajax异步提交参数的最大上线为8000个字节。

第二次尝试

在第一次的基础上对所获取到的base编码进行分割上传

将所获取的base编码字符串分成几份并进行编号,在循环调用ajax进行发送

服务端接收到后对数据进行解码,以编号进行命名

接收完所有小文件后,调用后台方法将小文件进行合并

测试结果失败,当上传文件超过1G时,浏览器就崩溃了。应该是在读取文件时,文件过大,一次性读出返回base编码过大,导致页面崩溃。

第三次尝试

在第二次的基础上想着在读取文件获取编码的过程也进行分批读取来避免一次性读取过大的文件导致页面崩溃。

这边就要使用到H5的file.slice()来对文件进行分块,从而实现分批读取分批上传。

通过FlieReader对象来读取文件快

通过ajax将base编码异步发送到服务端

服务端接收数据进行解码和文件保存

测试成功,测试上传了快4G的文件。

(由于将文件进行了分段,所以在上传大文件时会发起大量的ajax请求,产生大量的并发,可能会导致页面再次崩溃。所以我才用错开请求的方式。减慢产生ajax请求的速度。)

具体实现代码

接下来贴点代码

前端框架:layui

后端框架:tp5

页面代码:

<div class="layui-form-item">
 <label class="layui-form-label">视频上传</label>
 <div class="layui-input-block layui-upload-video-btn">
 <ul>
 <li class="img-upload">
 <label></label>
 <input type="file" class="video-upload-file layui-upload-video-file-btn" name="file"/>
 <video width="320" height="240" controls style="display: none">
 <source src="" type="video/mp4">
 <source src="" type="video/ogg">
 您的浏览器不支持Video标签。
 </video>
 <span style="display: none">X</span>
 <input type="hidden" class="video-link-id" name="video_link_id" value="">
 </li>
 <li>//视频上传会比较久(上传完会有提示)</li>
 </ul>
 </div>
</div>

js代码:

$('.video-upload-file').on('change',function(){
 layer.msg('正在提交视频......');
 //隐藏按钮,显示进度条
 $('.layui-upload-video').hide();
 $('.layui-progress-ads').show();
 var loads_video = layer.load(2,{shade: [0.2, '#3a3535']}); //产生加载圈,禁止用户其他操作
 var thisFile = $(this);
 var reader=new FileReader();
 var file_size = this.files[0].size; //文件大小
 var limit = 8388608; //每次读取文件的大小
 // var limit = 1048000; //每次读取文件的大小
 var up_count = Math.ceil(file_size/limit); //总上传次数
 var type = this.files[0].type.substr(this.files[0].type.indexOf('/')+1); //文件类型
 var success_num = 0; //用于存放上传成功的数据的id
 var check = 1; //防止多次合并
 console.log('文件大小:'+this.files[0].size);
 console.log('文件类型:'+type);
 console.log('分割上传次数:'+up_count);
 //分段读取文件
 readFile(this.files[0], 0, limit);
 function readFile(file, num, limit){
 // console.log('第'+num+'次:'+num*limit);
 reader.readAsDataURL(file.slice(num*limit, (num+1)*limit));
 reader.onload = function(e){
 console.log(reader.result.length);
 console.log(reader.result);
 //异步base的数据传输到服务器
 ajax_way(reader.result, name, num+1, thisFile);
 if((num+1)*limit <= file_size){
 readFile(file, num+1, limit);
 }
 }
 }
 function ajax_way(data,name,num, thisFile){
 //避免一次性生成太多的请求
 if(num+1 > 60){
 // console.log('等待两秒');
 sleep(6000);
 // console.log('等待结束');
 }
 $.ajax({
 url: "<?= url('admin/video/up_mfile');?>",
 type: "POST",
 data: {video:data,name:name,num:num},
 // async:false, //是否采用同步,串行发送请求
 success: function (data) {
 if(data.code == 1){
 //上传成功,成功次数加一
 success_num++;
 console.log(num+'完成');
 console.log('已完成:'+success_num+'/'+up_count);
 //计算完成的百分比
 var precentage = Math.ceil((success_num/up_count)*100);
 //更改进度条显示
 $('.layui-progress-ads-btn').attr('lay-percent', precentage+'%');
 $('.layui-progress-ads-btn').css('width', precentage+'%');
 $('.layui-progress-text').html(precentage+'%');
 //如果分割文件都上传了则调用接口合并文件
 if(success_num == up_count && check == 1){
 check = 0;
 success_num = 0;
 merge_mfile(name, up_count, thisFile, type);
 }
 }
 },
 error:function(e){
 console.log('出错了:'+num);
 //传输出错则重新上传
 ajax_way(data, name, num, thisFile);
 }
 });
 }

 //合并文件
 function merge_mfile(name, count, thisFile, type){
 $.ajax({
 url:"<?= url('admin/video/merge_mfile');?>",
 data:{name:name, count:count, type:type},
 type:"POST",
 success:function(data){
 if (data.code==1){
 layer.close(loads_video);
 layer.msg('视频提交成功');
 thisFile.siblings('.video-link-id').val(data.data);
 }else{
 layer.msg('视频提交异常请重新提交');
 //显示按钮,隐藏进度条
 $('.layui-upload-video').show();
 $('.layui-progress-ads').hide();
 //将进度条置零
 $('.layui-progress-ads-btn').attr('lay-percent', '0%');
 $('.layui-progress-ads-btn').css('width', '0%');
 $('.layui-progress-text').html('0%');
 //清空已选中的文件
 var file = $(".layui-upload-video-file-btn");
 file.after(file.clone().val(""));
 file.remove();
 }
 }
 })
 }
 function sleep(n) { //n表示的毫秒数
 var start = new Date().getTime();
 while (true) if (new Date().getTime() - start > n) break;
 }
 return false;
 });

更多layui知识请关注layui使用教程栏目。

文档

tp5+layui实现上传大文件介绍

tp5+layui实现上传大文件介绍:首先记录下更改文件上传大小的一些配置信息.打开php.inifile_uploads = on //是否允许通过HTTP上传文件的开关,默认开启upload_tmp_dir //临时文件储存的路径upload_max_filesize 20M //允许上传的文件最大值post_max_size 22M //通
推荐度:
标签: 上传 介绍 实现
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top