资讯专栏INFORMATION COLUMN

前端h5文件切片上传,后台php接收切片并合并

whinc / 1950人阅读

摘要:网上很多文件切片上传的文章看了很多最终自己总结了下主要思路如下需要实现的功能前端多文件上传前端文件切片并命名文件同步上传切片同步上传后端接受切片并根据文件名称保存至文件夹后端判断是否是最后一个切片合并切片用到的技术文件切片切片上传请求参数

网上很多文件切片上传的文章, 看了很多, 最终自己总结了下, 主要思路如下:

1. 需要实现的功能

前端多文件上传

前端文件切片, 并命名uuid

文件同步上传, 切片同步上传

后端接受切片并根据文件名称保存至文件夹

后端判断是否是最后一个切片,合并切片

2.用到的技术

h5文件切片

切片上传请求参数:

filename: file-5bad6aab-cf7d-bfdb-356a-36d7b4ab1e1e.jpg
fragname: frag-1e0d1311-2369-317b-262e-04a9f427ea8c
file: (binary)
fragindex: 0
total: 2

es6 async await

php monolog composer包

3. 开始写代码 3.1 前端

html:


点击上传, 获取所有的文件,并处理文件

 $("#upload").click(function () {
            var file = document.getElementById("file");
            //获取所有文件
            var fileList = file.files;

            //操作文件
            handleFiles(fileList);

            return false;
        });

处理文件方法:
文件上传同步,上传文件

async function handleFiles(fileList) {
            var i = 0;
            while (i

处理上传文件切片,并上传

//upload file
        async function uploadFile(targetFile,index) {
            //console.log(targetFile);
            var tmp = targetFile.name.split(".");
            var filename = "file-"+guid() + "." + tmp[tmp.length-1] ;
            var fileSize = targetFile.size;
            var total =  Math.ceil( fileSize / pieceSize );

            await handle();

            async function handle() {
                var i = 0;
                var start = end = 0;
                while(i < total){
                    end = start + pieceSize;

                    if(end >= fileSize){
                        end = fileSize;
                    }

                    console.log( "文件的index:" + index+ "| 处理文件切片 i:"+i , "start:" + start,  "end:" + end );
                    var frag = targetFile.slice(start, end);

                    await send( filename,frag,i , total ,function () {
                        console.log( "文件的index:" + index+ "| 切片上传完成 回调 res111",i)
                    });
                    start = end;
                    i++;
                }
            }
        }

        //send
        async function send(filename,frag,index,total,cb) {

            var formData = new FormData();
            var fragname = "frag-" + guid();

            formData.append("filename",filename);
            formData.append("fragname",fragname);
            formData.append("file",frag);
            formData.append("fragindex",index);
            formData.append("total",total);

            await $.ajax({
                url: url,
                type: "POST",
                cache: false,
                data: formData,
                processData: false,
                contentType: false
            }).done(function (res) {
                //console.log("res:" + index);
                cb && cb();
            }).fail(function (res) {
            });
        }
3.2 后台php
pushHandler(new StreamHandler(__DIR__."/my_app.log", Logger::DEBUG));

$file = $_FILES["file"];

//打印文件
$log->info("切片",$file);

$orgFileName = $_POST["filename"];
$log->info("orgFileName:" . $orgFileName);

//获取文件名称
$filename = explode("." , $_POST["filename"]);

//获取文件后缀
$ext = $filename[1];
$filename = $filename[0];

$log->info("ext:" . $ext);

//新建frag 文件夹, 以filename为命名方式
if(!file_exists(FRAGPATH.$filename)){
    mkdir(FRAGPATH.$filename);
}

//将接收到的frag文件移入file文件夹中
//$frag_path = SITE_ROOT."/dir/".$filename."/".iconv("UTF-8","gbk",basename($_FILES["file"]["tmp_name"]));
$frag_path = FRAGPATH.$filename ."/". $_POST["fragname"];
try{
    if(move_uploaded_file($_FILES["file"]["tmp_name"] , $frag_path)){
        echo response(["status" => "上传成功"]);
    }
}catch (Exception $e){
    throw new Exception();
}

//合并file文件夹中的frag为最终文件
if( $_POST["fragindex"] == $_POST["total"] -1 ){
    $blob = "";
    $fragDir = FRAGPATH.$filename;

    $handler = @opendir($fragDir);

    //获取filename
    while ( ( $fragFileName = readdir($handler) ) !== false ){
        $fp = fopen( FILEPATH . "/" . $orgFileName,"ab" );
        // 务必使用!==,防止目录下出现类似文件名“0”等情况
        if ($fragFileName !== "." && $fragFileName !== "..")
        {
            //方式一:
            //$blob .= file_get_contents( $fragDir . "/" . $fragFileName );

            //方式二:
            $value = $fragDir . "/" . $fragFileName;
            $handle = fopen($value,"rb");
            fwrite($fp,fread($handle,filesize($value)));
            fclose($handle);

            //删除切片文件
            @unlink($fragDir . "/" . $fragFileName);
        }
    }

    //合并切片到文件
    //file_put_contents( FILEPATH. "/" . $filename . ".". $ext , $blob );

    //删除切片文件夹
    @rmdir($fragDir);
}

最终文件上传成功删除切片文件夹下的切片

完整代码地址:https://github.com/lilili001/...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/29610.html

相关文章

  • Node+H5实现大文件分片上传(有源码)

    摘要:话前上传大文件上传的教程网上很多但是大部分没给出一个比较完整的出来这个博客给出的是前后端一套完整的解决方案其中前端没有使用第三方上传库希望能帮到有同样需求的朋友们大文件分片上传的好处在这里就不用多说了之前不管是上传单文件还是分片文件上传都是 话前 上传大文件上传的教程网上很多, 但是大部分没给出一个比较完整的出来, 这个博客给出的是前后端一套完整的解决方案, 其中前端没有使用第三方上传...

    1treeS 评论0 收藏0
  • 关于大文件上传

    showImg(https://segmentfault.com/img/bVbs1lu?w=675&h=221); 关于大文件上传 思路 使用js读取form表单中选择的file,计算文件md5值,并上传md5值到服务端,检查文件是否已上传过(类似秒传功能) 若文件未上传过,按照其大小切成1MB大小的块,小于1MB的不用切 用ajax异步提交切好的块上传至服务端(一个块一个请求,不阻塞,多线程...

    shusen 评论0 收藏0
  • 关于大文件上传

    showImg(https://segmentfault.com/img/bVbs1lu?w=675&h=221); 关于大文件上传 思路 使用js读取form表单中选择的file,计算文件md5值,并上传md5值到服务端,检查文件是否已上传过(类似秒传功能) 若文件未上传过,按照其大小切成1MB大小的块,小于1MB的不用切 用ajax异步提交切好的块上传至服务端(一个块一个请求,不阻塞,多线程...

    zollero 评论0 收藏0
  • js实现文件切片上传,断点续传

    摘要:思路很简单,拿到文件,保存文件唯一性标识,切割文件,分段上传,每次上传一段,根据唯一性标识判断文件上传进度,直到文件的全部片段上传完毕。 思路很简单,拿到文件,保存文件唯一性标识,切割文件,分段上传,每次上传一段,根据唯一性标识判断文件上传进度,直到文件的全部片段上传完毕。 以下文字没有完整的代码,只有基础理论,伸手党绕道。 读取文件 var input = document.quer...

    widuu 评论0 收藏0

发表评论

0条评论

whinc

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<