• html5文件上传断点续传


    最近公司要做一个html5上传的jquery插件,要在下先实现功能,要求显示上传进度,文件信息,断点续传等等。我一看,艾玛!Σ(゚д゚lll),没做过啊。没办法,(# ゚Д゚),只能去查资料了。
    作为一名还未毕业的大学僧,本人表示亚历山大。不过还好是做出来了,不敢说代码写得很好,大家将就着看吧。
    感谢以下文章提供的思考方向:
    http://www.script-tutorials.com/pure-html5-file-upload/
    http://fex.baidu.com/blog/2014/04/html5-uploader/

    由于传的时候不小心,文件弄错了,现在bug已修复,对不起啊大家
    考虑到服务器原因现在停止上传演示页面,抱歉请大家谅解
    演示地址:暂停
    资源地址:我是下载地址

    HTML:

    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">
    <title>upload html5</title>
    <link rel="stylesheet" type="text/css" href="css/style.css">
    <link rel="stylesheet" type="text/css" href="css/upload.css">
    </head>
    <body ontouchmove="event.preventDefault()">
    <div id="upload_box">
        <form id="upload_form" name="upload_form" action="javascript:init();" method="post" enctype="multipart/form-data">
            <div><label for="file">Please select file</label></div>
            <div><input type="file" id="file" name="file" onchange="fileReady()"><div>
            <input type="submit" id="submit" name="submit" value="上传">
            <button id="clear" onclick="clearUploadFile()">清除</button>
            <div class="upload_message_show">
                <!--进度条-->
                <div class="upload_bar_box">
                    <div class="upload_bar"></div>
                    <span class="upload_percent"></span>
                </div>
                <!--上传剩余时间和上传速度-->
                <div class="upload_count">
                    <div class="left_time">剩余时间 | 00:00:00</div>
                    <div class="speed">100k/s</div>
                </div>
                <!--文件信息-->
                <div class="upload_file_message">
                    <div class="message_box">
                        <div class="upload_file_name"></div>
                        <div class="upload_file_size"></div>
                        <div class="upload_file_type"></div>
                        <div class="upload_file_error"></div>
                        <div class="isCompleted"></div>
                    </div>
                    <!--文件预览-->
                    <div class="upload_file_preview"></div>
                </div>
            </div>
        </div>
    <script type="text/javascript" src="js/html5_upload_ano.js"></script>
    </body>
    </html>

    CSS:

    style.css

    /*************reset****************/
    html{color:#333;-webkit-text-size-adjust:none;height:100%;max-height:100%;overflow: hidden;font-family: 'Microsoft Yahei';}
    body{height: 100%;max-height:100%;overflow: hidden;}
    body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;}
    table{border-collapse:collapse;border-spacing:0;}
    fieldset,img{border:0;}
    address,caption,cite,code,dfn,em,var,optgroup{font-style:inherit;font-weight:inherit;}
    del,ins{text-decoration:none;}
    li{list-style:none;}
    h1,h2,h3,h4,h5,h6{font-size:100%;}q:before,q:after{content:'';}
    abbr,acronym{border:0;font-variant:normal;}
    sup{vertical-align:baseline;}
    sub{vertical-align:baseline;}legend{color:#000;}
    input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;}
    body{font-size:12px;}
    a{color: #333333;text-decoration: none;}
    a:hover{text-decoration:underline; color:#c00;}
    
    /*font*/
    *{
        font-size: 1.05em;
        color: #222;
        font-family: "Microsoft Yahei";
    }

    upload.css

    #upload_box{
        padding:0em 1em;
        padding-top:20px;
        height:100%;
        background: #74b1d1;
        position: relative;
    }
    
    #upload_form{
        background: #fff;
        height: 80%;
        padding: 1.4em 1em;
        border-radius: 4px;
        box-shadow: 0 1px 3px rgba(0,0,0,0.7);
    }
    
    #upload_form label{
        font-size: 1.5em;
        font-weight: bolder;
    }
    
    #file{
        margin:20px 0;
        border:1px solid #ccc;
        border-radius: 5px;
        padding: 0.5em;
        font-size: 1.4em;
         90%;
    }
    
    #submit,#clear{
        font-size:1.2em;
        padding:0.3em 1.2em;
        border-radius:10px;
        border:1px solid #d9d9d9;
        background: -webkit-linear-gradient(#ffffff,#dfdfdf);
        background: -o-linear-gradient(#ffffff,#dfdfdf);
        background: -moz-linear-gradient(#ffffff,#dfdfdf);
        background: linear-gradient(#ffffff,#dfdfdf);
        box-shadow:0px 1px 3px rgba(0,0,0,0.7);
        outline: none;
    }
    
    #submit{
        margin-right:1.6em;
    }
    
    #submit:hover,#clear:hover{
        background: -webkit-linear-gradient(#66ccff,#74b1d1);
        background: -o-linear-gradient(#66ccff,#74b1d1);
        background: -moz-linear-gradient(#66ccff,#74b1d1);
        background: linear-gradient(#66ccff,#74b1d1);
        cursor: pointer;
    }
    
    .upload_message_show{
        margin-top: 20px;
        display: none;
    }
    
    .upload_file_message{
        padding: 1.4em 0em;
        padding-left: 60%;
        padding-right: 1.2em;
        border-radius: 10px;
        background: -webkit-linear-gradient(#dfdfdf,#cccccc);
        background: -o-linear-gradient(#dfdfdf,#cccccc);
        background: -moz-linear-gradient(#dfdfdf,#cccccc);
        background: linear-gradient(#dfdfdf,#cccccc);
        font-size: 1.1em;
        font-weight: bolder;
        position: relative;
        min-height: 6.5em;
    }
    
    .upload_file_error{
        color:red;
    }
    
    .message_box{
        position: absolute;
        left: 1.2em;
        top: 1.4em;
    }
    
    .upload_file_preview{
        height: 100%;
        position: relative;
    }
    
    .upload_bar_box{
         100%;
        height: 1em;
        border-radius:0.5em;
        position: relative;
        box-shadow:0px 0px 3px rgba(0,0,0,0.6);
        line-height: 1em;
    }
    
    .upload_bar{
        0%;
        border-radius:0.5em;
        background:-webkit-linear-gradient(#F01731,#F50B43);
        background:-o-linear-gradient(#F01731,#F50B43);
        background:-moz-linear-gradient(#F01731,#F50B43);
        background:linear-gradient(#F01731,#F50B43);
        height:100%;
    }
    
    .upload_percent{
        position: absolute;
        right: 10px;
        top:0em;
        font-weight:700;
    }
    
    .upload_count{
         100%;
        font-size:0.8em;
        margin-top:1em;
        position: relative;
    }
    
    .left_time{
        margin-left: 1em;
    }
    
    .speed{
        position: absolute;
        right:1em;
        top: 0em;
    }

    js:

    变量定义:

    var nSlice_count = 100,//分段数,文件分段数
        nFactCount,           //实际分段数
        nMin_size      = 0.5,//最小分段大小(M)
        nMax_size     = 5,  //最大分段大小(M)
        nFactSize,           //实际分段大小
        nCountNum     = 0,  //分段标号
        sFile_type,           //文件类型
        nFile_load_size,   //文件上传部分大小
        nFile_size,           //文件大小
        nPreuploaded = 0,  //上一次记录上传部分的大小
        bIs_uploading= false,//是否上传中
        bStart_upload= false,//是否开始上传
        bEnd_upload  = false;//是否上传完成

    当文件域变化或者点击清空时,重置所有已记录信息:

    function messageChange(){
        document.querySelector(".upload_file_name").innerHTML ="文件名称: " ;
        document.querySelector(".upload_file_type").innerHTML ="文件类型: " ;
        document.querySelector(".upload_file_size").innerHTML ="文件大小: " ;
        document.querySelector(".isCompleted").innerHTML       ="上传状态: " ;
        document.querySelector(".upload_bar").style.width = "0%";
        document.querySelector(".upload_percent").innerHTML = "0%";
        document.querySelector(".upload_file_preview").innerHTML ="";
        document.querySelector(".upload_message_show").style.display = "none";
    }
    
    function clearUploadFile(e){
        var e = e || event;
        e.stopPropagation();
        e.preventDefault();
        document.getElementById("file").value = "";
        bStart_upload = false;
        messageChange();
    }
    
    
    function fileReady(){
        bIs_uploading = false;
        bEnd_upload = false;
        nCountNum = 0;
        bStart_upload = false;
        messageChange();
    }

    发生错误时的处理:

    function errorUp(){
        bStart_upload = false;
        document.querySelector(".upload_file_error").innerHTML = "上传过程中出错";
    }
    
    function abortUp(){
        bStart_upload = false;
        document.querySelector(".upload_file_error").innerHTML = "网络故障,请检查重试";
    }

    文件上传后提供预览,考虑到手机小屏幕的问题,只在ipad和pc上提供预览,预览的文件类型为
    image/video/audio,由于浏览器对多媒体格式的支持不同,不能保证每个文件都能正常播放

    function filePreview($src){
        var ftype = sFile_type;
        var $temp;
        var IMGMaxHeight = document.querySelector(".upload_message_show").offsetHeight;
        switch(ftype){
            case "image" :
            $temp = '<img src="source/'+$src.url+'" style="max-height:'+IMGMaxHeight+'px;margin-left:30%;">';
            break;
            case "audio" :
            $temp = '<audio src="source/'+$src.url+'" controls="controls"></audio>';
            break;
            case "video" :
            $temp = '<video src="source/'+$src.url+'" controls="controls"></video>';
            break;
        }
        var IsPreview = checkUserAgent();
    
        if(IsPreview)
        document.querySelector(".upload_file_preview").innerHTML = $temp;
    }
    
    function checkUserAgent(){
        var msg = true;
        var agent = ["ipod","iphone","android","symbian","windows mobile"];
        var info =navigator.userAgent.toLowerCase();
        
        for(var i=0,j=agent.length;i<j;i++)
        {
            if(info.indexOf(agent[i])>0)
            msg = false;
        }
    
        return msg;
    }

    数据单位转化:

    var conversion = (function(){
            var unitConversion = {
                bytesTosize:function(data){
                    var unit = ["Bytes","KB","MB","GB"];
                    var i = parseInt(Math.log(data)/Math.log(1024));
                    return (data/Math.pow(1024,i)).toFixed(1) + " " + unit[i];
                },
                secondsTotime:function(sec){
                    var h = Math.floor(sec/3600),
                        m = Math.floor((sec-h*3600)/60),
                        s = Math.floor(sec-h*3600-m*60);
                    if(h<10) h = "0" + h;
                    if(m<10) m = "0" + m;
                    if(s<10) s = "0" + s;
    
                    return h + ":" + m + ":" + s + ":";
                }
            };
    
            return unitConversion;
        })();

    文件上传和上传时的计算:

    //start sending
        var reader = new FileReader();
        var timer;
    
        var fProgress = function(e){
            var fSize = get_file_message.getAll().fileSize;
            timer = setTimeout(uploadCount(e,fSize,conversion),300);
        };
    
        var floadend = function(e){
            if(reader.error){alert("上传失败,出现未知错误");clearTimeout(timer);return;}
            clearTimeout(timer);
            if(nCountNum+1!=nFactCount)
            {
                if(bStart_upload)
                {
                    nCountNum++;
                    uploadStart();
                    return;
                } else {
                    document.querySelector(".speed").innerHTML = "0k/s";
                    document.querySelector(".left_time").innerHTML = "剩余时间 | 00:00:00";
                    return;
                }        
            }
    
            bEnd_upload = true;
            document.querySelector(".layer_box").style.display = "none";
            document.querySelector(".speed").innerHTML = "0k/s";
            document.querySelector(".left_time").innerHTML = "剩余时间 | 00:00:00";
            document.querySelector(".upload_percent").innerHTML = "100.00%";
            document.getElementById("submit").value = "上传";
            
            var $res = JSON.parse(e.target.responseText);
            filePreview($res);
            if($res.res=="success") bIs_uploading =true;
            document.querySelector(".isCompleted").innerHTML="上传状态: " + (bIs_uploading?"上传完成":"正在上传..");
        };
    
        var uploadStart = function(){
            var get_all = get_file_message.getAll();
            var start = nCountNum * nFactSize,
                end   = Math.min(start+nFactSize,get_all.fileSize);
    
            var fData = new FormData();
    
            fData.append("file",file.slice(start,end));
            fData.append("name",file.name);
            fData.append("size",file.size);
            fData.append("type",file.type);
            fData.append("totalCount",nFactCount);
            fData.append("indexCount",nCountNum);
            fData.append("trueName",file.name.substring(0,file.name.lastIndexOf(".")));
    
            
            document.querySelector(".layer_box").style.display = "block";
            if(!sFile_type)
            sFile_type = file.type.substring(0,file.type.indexOf("/"));
            var xhr = new XMLHttpRequest();
            xhr.upload.addEventListener("progress",fProgress,false);
            xhr.addEventListener("load",floadend,false);
            xhr.addEventListener("error",errorUp,false);
            xhr.addEventListener("abort",abortUp,false);
            
            xhr.open("POST","php/send/");
            xhr.send(fData);
        };
    
        reader.onloadstart = function(){
            var get_all = get_file_message.getAll(),
                fName = get_all.fileName,
                fType = get_all.fileType,
                fSize = conversion.bytesTosize(get_all.fileSize);
    
            document.querySelector(".upload_message_show").style.display = "block";
            document.querySelector(".upload_file_name").innerHTML ="文件名称: " + fName;
            document.querySelector(".upload_file_type").innerHTML ="文件类型: " + fType;
            document.querySelector(".upload_file_size").innerHTML ="文件大小: " + fSize;
            document.querySelector(".isCompleted").innerHTML       ="上传状态: " + (bIs_uploading?"完成":"正在上传中..");
    
            nFactSize = get_all.fileSize/nSlice_count;
            nFactSize = (nFactSize>=nMin_size*1024*1024?nFactSize:nMin_size*1024*1024);
            nFactSize = (nFactSize<=nMax_size*1024*1024?nFactSize:nMax_size*1024*1024);
            nFactCount= Math.ceil(get_all.fileSize/nFactSize);
    
            uploadStart();
        };
    
    
        reader.readAsBinaryString(file);
    }
    
    function uploadCount(e,fSize,conversion){
        var upSize = e.loaded+nCountNum*nFactSize,
            perc = (upSize*100/fSize).toFixed(2) + "%";
        var speed = Math.abs(upSize - nPreuploaded);
        if(speed==0){clearTimeout("timer");return;}
        var leftTime = conversion.secondsTotime(Math.round((fSize-upSize)/speed));
        speed = conversion.bytesTosize(speed)+"/s";
        document.querySelector(".speed").innerHTML = speed;
        document.querySelector(".left_time").innerHTML = "剩余时间 | " + leftTime;
        document.querySelector(".upload_percent").innerHTML = perc;
        document.querySelector(".upload_bar").style.width = perc;
        nPreuploaded = upSize;
    }

    PHP:

    <?php
    
    $fsize = $_POST['size'];
    $findex =$_POST['indexCount'];
    $ftotal =$_POST['totalCount'];
    $ftype = $_POST['type'];
    $fdata = $_FILES['file'];
    $fname = mb_convert_encoding($_POST['name'],"gbk","utf-8");
    $truename = mb_convert_encoding($_POST['trueName'],"gbk","utf-8");
    
    $path = "../../";
    $dir = $path."source/".$truename."-".$fsize;
    $save = $dir."/".$fname;
    if(!is_dir($dir))
    {
        mkdir($dir);
        chmod($dir,0777);
    }
    
    //读取临时文件内容
    $temp = fopen($fdata["tmp_name"],"r+");
    $filedata = fread($temp,filesize($fdata["tmp_name"]));
    //将分段内容存放到新建的临时文件里面
    if(file_exists($dir."/".$findex.".tmp")) unlink($dir."/".$findex.".tmp");
    $tempFile = fopen($dir."/".$findex.".tmp","w+");
    fwrite($tempFile,$filedata);
    fclose($tempFile);
    
    fclose($temp);
    
    if($findex+1==$ftotal)
    {
        if(file_exists($save)) @unlink($save);
        //循环读取临时文件并将其合并置入新文件里面
        for($i=0;$i<$ftotal;$i++)
        {
            $readData = fopen($dir."/".$i.".tmp","r+");
            $writeData = fread($readData,filesize($dir."/".$i.".tmp"));
    
            $newFile = fopen($save,"a+");
            fwrite($newFile,$writeData);
            fclose($newFile);
            
            fclose($readData);
    
            $resu = @unlink($dir."/".$i.".tmp"); 
        }
        $res = array("res"=>"success","url"=>mb_convert_encoding($truename."-".$fsize."/".$fname,'utf-8','gbk'));
        echo json_encode($res);
    }
    
    ?>

    还有一些细节的js这里没给出来,主要就上面的功能,有问题的话欢迎回复,楼主只是个新手,不足之处请大家多多见谅。

  • 相关阅读:
    iPhone 12 Pro 不锈钢边框刮伤 All In One
    .vscodeignore All In One
    程序员如何挑选和购买一款高性价比的电动升降桌 All In One
    TypeScript function arguments destructuring All In One
    LeetCode 旋转数组算法题解 All In One
    python 中实现DNA一致性序列计算
    python中输出两条长度一致序列碱基不同的个数
    python 中统计不同scafflod的GC含量并输出GC含量最高的scafflod
    python 中 斐波那契兔子问题
    python 中如何将列表中的数值转换为字符串
  • 原文地址:https://www.cnblogs.com/10manongit/p/12972572.html
Copyright © 2020-2023  润新知