大文件断点上传 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 + '次,上传文件有误!');

} else {

console.log('未知错误');

}

},

error: function(msg) {

console.log(2);

console.log(msg.status);

}

})

}