To clarify the idea:
Two concepts are introduced: block and slice (chunk). Each block consists of one or more slices, and a resource consists of one or more blocks
Blocks are permanent data storage units on the server side, and slices are only temporary storage units during the fragment upload process. The server will periodically purge data slices that have not been merged into blocks for about one months
Implementation process:
Split file, fragment upload, then merge
Front-End core code:
var fileform = document.getElementById ("file");
var upstartbtn = document.getElementById (' upstart ');
var stopbtn = document.getElementById (' Stop ');
var startbtn = document.getElementById (' restart ');
var rate = document.getElementById (' rate ');
var divlog = document.getElementById (' Divlog ');
---------------------------Const LENGTH = 1024 * 1024 * 1;
var start = 0;
var end = start + LENGTH;
var blob;
var blob_num = 1;
var is_stop = 0 var file = null;
var md5filename = ';
-----------------------------var upload_instance = new upload (); Fileform.onchange = function () {browsermd5file (Fileform.files[0], function (err, MD5) {//If file is large, MD5 value generates slower MD5 value generation to Upload processing, the optimization of their own md5filename = MD5;
If you need to refresh the breakpoint can also be used to record the cookie, the perfect divlog.innerhtml = ' file md5 as: ' + md5filename;
});
} Upstartbtn.onclick = function () {upload_instance.addfileandsend (fileform); } Stopbtn.onclick = function () {upload_instance.stop ();
} Startbtn.onclick = function () {Upload_instance.start ();
function Upload () {var xhr = new XMLHttpRequest ();
var form_data = new FormData ();
External method, incoming file Object this.addfileandsend = function (that) {file = That.files[0];
Blob = cutfile (file);
SendFile (Blob,file);
Blob_num + 1;
//stop file Upload this.stop = function () {xhr.abort ();
Is_stop = 1;
} This.start = function () {sendFile (blob,file);
is_stop = 0;
}//Cut file function Cutfile (files) {var File_blob = File.slice (start,end);
start = end;
End = start + LENGTH;
return file_blob;
};
Send file function SendFile (blob,file) {var total_blob_num = Math.ceil (file.size/length);
Form_data.append (' file ', blob);
Form_data.append (' Blob_num ', blob_num);
Form_data.append (' Total_blob_num ', total_blob_num); Form_data.append (' Md5_file_name ', md5fIlename);
Form_data.append (' file_name ', file.name);
Xhr.open (' POST ', './index.php ', false);
Xhr.onreadystatechange = function () {var progress;
var progressobj = document.getElementById (' Finish ');
if (Total_blob_num = = 1) {progress = ' 100% ';
}else{progress = (Math.min (blob_num/total_blob_num) *). ToFixed (2) + '% ';
} console.log (' Progress-----' +progress);
ProgressObj.style.width = progress;
rate.innerhtml = progress; var t = settimeout (function () {if (Start < file.size && Is_stop = = 0) {blob = Cutfile (fil
e);
SendFile (Blob,file);
Blob_num + 1;
}else{//settimeout (t);
}},1000);
} xhr.send (Form_data); }
}
Back-end Code
<?php class upload{Private $filepath = './upload ';//upload directory private $tmpPath//php files temporary directory private $blobNum;//The first few File Block private $totalBlobNum; Total number of file blocks private $fileName;
File name private $MD 5FileName;
Public function __construct ($tmpPath, $blobNum, $totalBlobNum, $fileName, $md 5FileName) {$this->tmppath = $tmpPath;
$this->blobnum = $blobNum;
$this->totalblobnum = $totalBlobNum;
$this->filename = $this->createname ($fileName, $MD 5FileName);
$this->movefile ();
$this->filemerge ();
//Determine if it is the last piece, and if so, file synthesis and delete file block private Function Filemerge () {if ($this->blobnum = = $this->totalblobnum) {
$blob = '; For ($i =1 $i <= $this->totalblobnum; $i + +) {$blob. = file_get_contents ($this->filepath. ') /'. $this->filename. '
__ '. $i); } file_put_contents ($this->filepath. ' /'.
$this->filename, $blob);
$this->deletefileblob (); }///delete file block Private Function Deletefileblob () {
For ($i =1 $i <= $this->totalblobnum; $i + +) {@unlink ($this->filepath. ') /'. $this->filename. '
__ '. $i);
The Private Function MoveFile () {$this->touchdir (); $filename = $this->filepath. ' /'. $this->filename. '
__ '. $this->blobnum;
Move_uploaded_file ($this->tmppath, $filename); //API returns the data public function Apireturn () {if ($this->blobnum = = $this->totalblobnum) {if (File_exis TS ($this->filepath. ' /'.
$this->filename)) {$data [' code '] = 2;
$data [' msg '] = ' success '; $data [' file_path '] = ' http://'. $_server[' Http_host '].dirname ($_server[' Document_uri ']). Str_replace ('. ', ', ', $this- >filepath). ' /'.
$this->filename; }else{if (file_exists ($this->filepath. ') /'. $this->filename. '
__ '. $this->blobnum)) {$data [' code '] = 1;
$data [' msg '] = ' waiting ';
$data [' file_path '] = '; } header (' Content-type:application/json ');
echo Json_encode ($data);
Private Function Touchdir () {if (!file_exists ($this->filepath)) {return mkdir ($this->filepath); The Private function Createname ($fileName, $md 5FileName) {return $MD 5FileName. '.' .
PathInfo ($fileName) [' extension ']; } $upload = new upload ($_files[' file '] [' tmp_name '],$_post[' blob_num '],$_post[' ' total_blob_num '],$_post[' ' file_name ')
],$_post[' Md5_file_name ']); $upload->apireturn ();
Complete code, Download here = ""
https://download.csdn.net/download/qq43599939/10319668