1. 程式人生 > >大檔案斷點上傳 js+php

大檔案斷點上傳 js+php

/*
* js
*/
function
PostFile(file, i, t) {      console.log(1);    var name = file.name,   //檔名   size = file.size,   type = file.type,   //總大小shardSize = 2 * 1024 * 1024,   shardSize = 2 * 1024 * 1024,   //以2MB為一個分片,每個分片的大小   shardCount = Math.ceil(size / shardSize);  //總片數     
  if (i >= shardCount) {     return;   }     //console.log(size,i+1,shardSize);  //檔案總大小,第一次,分片大小//        var start = i * shardSize;       var end = start + shardSize;       var packet = file
.slice(start, end);  //將檔案進行切片   /*  構建form表單進行提交  */        var form = new FormData();       form.append("data", packet); //slice方法用於切出檔案的一部分        form.append("lastModified", file.lastModified); //最後的額修改時間
       form.append("name", name);       form.append("type", type);       form.append("totalsize", size);       form.append("total", shardCount); //總片數        form.append("index", i + 1); //當前是第幾片   form.append("_cfs", $.cookie('_cfc'));       $.ajax({           formData: {     _cfs: $.cookie('_cfc')     },     url: uploaddo_url,     type: "POST",     data: form,     //timeout:"10000",   async: true, //非同步     dataType: "json",     processData: false, //很重要,告訴jquery不要對form進行處理     contentType: false, //很重要,指定為false才能形成正確的Content-Type     success: function(msg) {                    console.log(msg.status);         /*  表示上一塊檔案上傳成功,繼續下一次  */                if (msg.status == 201) {             form = '';                   i++;                   PostFile(file, i, t);          } else if (msg.status == 502) {                   form = '';           /*  失敗後,每2秒繼續傳一次分片檔案  */                    setInterval(function() { PostFile(file, i, t) }, 2000);                 console.log("上傳失敗");       } else if (msg.status == 200) {         console.log("上傳成功");                } else if (msg.status == 500) {         console.log('第' + msg.i + '次,上傳檔案有誤!');       } else {          console.log('未知錯誤');       }           },     error: function(msg) {       console.log(2);       console.log(msg.status);     }   })    }

php程式碼示例

public function video(){
        
        $files = $_FILES['data'];
        
        $arr['i'] = $this->input->post('index');
        $arr['shardCount'] = $this->input->post('total');
        $arr['totalsize'] = $this->input->post('totalsize');
        $arr['fileName'] = $this->input->post('name');
        $arr['type'] = $this->input->post('type');
        
        

        if($files['error'] > 0) {
            $arr['status'] = 502;
            exit(json_encode($arr));
        }
        
        
        /*  檢測第一次上傳的時候已經有同文件時,刪除原來的檔案  */
        if ($arr['i'] == 1 && is_file(UPLOAD_PATH. $arr['fileName']) && filesize(UPLOAD_PATH. $arr['fileName']) == $arr['totalsize']){
            unlink(UPLOAD_PATH. $arr['fileName']);
        }
        
        
        // 否則繼續追加檔案資料
        if (!file_put_contents(UPLOAD_PATH.$arr['fileName'],file_get_contents($files['tmp_name']),FILE_APPEND)) {
            $arr['status'] = 501;
            exit(json_encode($arr));
        }
        
        // 在上傳的最後片段時,檢測檔案是否完整(大小是否一致)
        if ($arr['i'] == $arr['shardCount']) {
            if(filesize(UPLOAD_PATH. $arr['fileName']) == $arr['totalsize']){
                $arr['status'] = 200;
                $this->CI =& get_instance();
                $this->CI->load->library('OssLibrary');
                $files = array();
                $content = file_get_contents(UPLOAD_PATH. $arr['fileName']);
                $files[] = OssLibrary::putObject($content, $arr['fileName'], $arr['totalsize'], $arr['type']);
                if ($files) {
                    unlink(UPLOAD_PATH. $arr['fileName']);
                    // 插入資料庫
                    $this->db_isnert($files);
                }
                $arr['data'] = $files;
                
            }else{
                $arr['status'] = 501;
            }
            exit(json_encode($arr));
        }
        $arr['status'] = 201;
        exit(json_encode($arr));
        
    }

 

function PostFile( file, i, t) {    console. log( 1);  var name = file. name, //檔名 size = file. size, type = file. type, //總大小shardSize = 2 * 1024 * 1024, shardSize = 2 * 1024 * 1024, //以2MB為一個分片,每個分片的大小 shardCount = Math. ceil( size / shardSize);  //總片數      if ( i >= shardCount) { return; }     //console.log(size,i+1,shardSize);  //檔案總大小,第一次,分片大小//      var start = i * shardSize;     var end = start + shardSize;     var packet = file. slice( start, end);  //將檔案進行切片      /*  構建form表單進行提交  */      var form = new FormData();     form. append( "data", packet); //slice方法用於切出檔案的一部分      form. append( "lastModified", file. lastModified); //最後的額修改時間      form. append( "name", name);     form. append( "type", type);     form. append( "totalsize", size);     form. append( "total", shardCount); //總片數      form. append( "index", i + 1); //當前是第幾片 form. append( "_cfs", $. cookie( '_cfc'));     $. ajax({       formData: { _cfs: $. cookie( '_cfc') }, url: uploaddo_url, type: "POST", data: form, //timeout:"10000", async: true, //非同步 dataType: "json", processData: false, //很重要,告訴jquery不要對form進行處理 contentType: false, //很重要,指定為false才能形成正確的Content-Type success : function( msg) { progressall( i + 1, shardCount);         console. log( msg. status);         /*  表示上一塊檔案上傳成功,繼續下一次  */          if ( msg. status == 201) {     form = '';           i++;          
PostFile( file, i, t);    } else if ( msg. status == 502) {           form = '';           /*  失敗後,每2秒繼續傳一次分片檔案  */            setInterval( function() { PostFile( file, i, t) }, 2000);         console. log( "上傳失敗"); } else if ( msg. status == 200) {
console. log( "上傳成功"); done( msg. data, t) } else if ( msg. status == 500) { console. log( '第' + msg. i + '次,上傳檔案有誤!'); } elseconsole. log( '未知錯誤'); }       }, error : function( msg) { console. log( 2); console. log( msg. status); } })   }