网页内实现大文件分片上传、断点续传

最近做公司的项目,需要在后台控制系统中添加一个功能-------向服务器发送程序更新包;这些程序更新包大小不固定,但基本都在1G到4G之间,刚开始还真是难倒我了,因为之前的项目中没有上传过这么大的文件,还要断点续传,后来经过查资料,写DEMO,这个问题终于解决了;

解决办法:

使用XMLHttpRequest来实现,将大文件分成小部分,分片上传,并事实的记录上传的进度,保证上传中断后,再次上传时还是从上一次中断的地方开始的;

下面就直接贴上我的demo代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>大文件上传</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
</head>
<body>

<div class="file-upload-box">
    <input id="file-input" type="file">
    <button onclick="stopup()" id="stop">上传</button>
</div>
<progress value="0" max="10" id="prouploadfile"  style="width:300px;"></progress>
<span id="persent">0%</span>

<script type="text/javascript">
    let fileInput=document.getElementById("file-input");
    let stopbutton = document.getElementById('stop');
    //上传进度
    let pro = document.getElementById('prouploadfile');
    let persent = document.getElementById('persent');

    fileInput.addEventListener("change",function(e){
        //获取文件对象
        let fileList = e.target.files;
        resultfile = fileList[0];
        //切片计算
        filesize= resultfile.size;//上传文件大小
        setsize=1000*1024;//定义切片大小
        filecount = filesize/setsize;//计算切片数量
        //定义进度条
        pro.max=parseInt(Math.ceil(filecount));
        i =getCookie(resultfile.name);
        i = (i!==null && i!=="")?parseInt(i):0;
        if(Math.floor(filecount)<i){
            alert("该文件已经上传完成,请勿重复上传!");
            pro.value=i+1;
            persent.innerHTML="100%";
        }else{
            pro.value=i;
            p=parseInt(i)*100/Math.ceil(filecount);
            persent.innerHTML=parseInt(p)+"%";
        }
    },false);
    //3.ajax上传
    let stop=1;
    function xhr2(){
        if(stop===1){
            return false;
        }
        if(resultfile===""){
            alert("请选择文件!");
            return false;
        }
        i=getCookie(resultfile.name);
        i = (i!=null && i!=="")?parseInt(i):0;
        if(Math.floor(filecount)<parseInt(i)){
            alert("已经上传完成!");
            return false;
        }
        let xhr = new XMLHttpRequest();//第一步
        //新建一个FormData对象
        let formData = new FormData();
        //追加文件数据
        //改变进度条
        pro.value=i+1;
        p=parseInt(i+1)*100/Math.ceil(filecount);
        persent.innerHTML=parseInt(p)+"%";
        //进度条
        if((filesize-i*setsize)>setsize){
            blobfile= resultfile.slice(i*setsize,(i+1)*setsize);
        }else{
            blobfile= resultfile.slice(i*setsize,filesize);
            formData.append('lastone', Math.floor(filecount));
        }
        formData.append('file', blobfile);
        formData.append('blobname', i);
        formData.append('filename', resultfile.name);
        //设置响应返回的数据格式
        //post方式
        xhr.open('POST', 'http://127.0.0.1:8081/largeFileUpload/data/fileSave.php'); //第二步骤
        //发送请求
        xhr.send(formData);  //第三步骤
        stopbutton.innerHTML = "暂停";
        //ajax返回
        xhr.onreadystatechange = function(){ //第四步
            if ( xhr.readyState === 4 && xhr.status === 200 ) {
                //请求成功
                //console.log(xhr.responseText);
                if(i<filecount){
                    xhr2();
                }else{
                    i=0;
                    alert("上传完成!");
                    window.location.reload();

                }
                if(xhr.responseText!=="not end"){
                    window.parent.$('#affixdiv').after(xhr.responseText);
                }else{
                    console.log('正在分片上传中('+Math.floor(filecount)+')...'+i);
                }
            }
        };
        //设置超时时间
        xhr.timeout = 20000;
        xhr.ontimeout = function(event){
            alert('请求超时,网络拥堵!\n(如果文件已经上传完成,请忽略此消息!)');
        };
        i=i+1;
        setCookie(resultfile.name,i,1);//Cookie有效时间1天
    }
    //设置cookie
    function setCookie(c_name,value,expiredays)
    {
        let exdate=new Date();
        exdate.setDate(exdate.getDate()+expiredays);
        document.cookie=c_name+ "=" +escape(value)+((expiredays==null) ? "" : ";expires="+exdate.toGMTString()+";path=/");
    }
    //获取cookie
    function getCookie(c_name)
    {
        if (document.cookie.length>0)
        {
            c_start=document.cookie.indexOf(c_name + "=");
            if (c_start!==-1)
            {
                c_start=c_start + c_name.length+1;
                c_end=document.cookie.indexOf(";",c_start);
                if (c_end===-1) c_end=document.cookie.length;
                return unescape(document.cookie.substring(c_start,c_end));
            }
        }
        return "";
    }
    function stopup(){
        if(stop===1){
            stop = 0;
            xhr2();
        }else{
            stop = 1;
            stopbutton.innerHTML = "继续";
        }
    }

</script>
</body>
</html>

在使用的时候需要将上传地址更改为自己的后台地址即可;

猜你喜欢

转载自blog.csdn.net/qq_41725450/article/details/82868464