Use html5’s new features to split files, to achieve the breakpoint function
Use spark. Js to obtain the MD5 file to ensure the uniqueness of the file
Process Overview:
(The front end of this function calls three interfaces, called A/B/C for short respectively) 1. Obtain file information: upload input using HTML5 native. After selecting the file, obtain all information of the file (filename, total bytes of the file, etc.) 2. Agree with the background on the size of a single slice, such as 1M/ slice, calculate the total file size/size of a single slice = the total number of slices 3, calculate the MD5 of files and the MD5 of each slice: Invoke spark-md5.min.js to generate MD5. The invocation of this JS can obtain md5 of file, MD5 of slice and data of slice 4. The key parameters that need to be passed to the background are file name, total file size and MD5 5 of the file. After obtaining the initial uploading position of the slice, the fragment uploading to the server starts formally: After obtaining the slice position from interface A, interface B is called to send MD5 and slice data of slices to the background. After that, interface B is repeatedly called until the uploading of all slices ends. 6Copy the code
Detailed code display:
HTML:
<input type='file' title="" accept=".mp4"
name='myfiles' id="mediaFile" class="" onchange="handleFile()" />
Copy the code
Obtain file information:
function handleFile() {
var fileInputs = $("input[name='myfiles']") [0]; // Get the file information in the input
// Store each item of the cut file separately
var name = fileInputs.files[0].name, / / file name
size = fileInputs.files[0].size, // Total bytes of the file
type = fileInputs.files[0].type, // File type
shardSize = 1024 * 1024.// The total number of bytes per slice, such as 1M as a slice
shardCount = Math.ceil(size / shardSize); / / the total number of pieces
}
Copy the code
Calculate the MD5 of the entire file: (the premise is to import spark. Js, download address:js-spark-md5)
var singleFileData = new Array(a);// Start an empty array to store all sliced data
var fileReader = new FileReader(),
blobSlice = File.prototype.mozSlice || File.prototype.webkitSlice || File.prototype.slice,
chunkSize = shardSize , // Total number of bytes for a single slice
chunks = shardCount, / / the total number of pieces
currentChunk = 0;
var spark = new SparkMD5.ArrayBuffer();
fileReader.onload = function (e) {
//******* gets the shard file for calculating MD5 for all slices
for (var i = 0; i < chunks; i++) {
var start = i * chunkSize,
end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
var sliceFile = blobSlice.call(file, start, end);
// Call this method to calculate the MD5 for each slice
getChunkMd5(sliceFile, i);
}
/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
spark.append(e.target.result);
if (currentChunk < chunks) {
currentChunk++;
loadNext();
} else {
var allFileEnd = spark.end()
console.log("This value is MD5 for the entire slice", allFileEnd)
/ / true MD5 value: allFileEnd = a0ce27800ee7d948422f3fe16e898f22
// *** call interface (1) to query the number of slices to upload *** from
// *** write the calling method *** of interface A here}};function loadNext() {
// Calculate the start and end of the slice, which are used to cut out the slice data
var start = currentChunk * chunkSize,
end = start + chunkSize >= file.size ? file.size : start + chunkSize;
fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
// Store sliced data
// Determine if singleFileData is less than the total number of slices, continue adding slice data to the array
if(singleFileData.length ! = chunks) { singleFileData.push(blobSlice.call(file, start, end))// Push each slice into an empty array}};// Call this method to loop through the slice data
loadNext()
Copy the code
Calculate the MD5 of slices:
(This step can be omitted, but for the sake of preciseness, the back end needs to calculate MD5 based on the slice data incoming from the front end, and compare the MD5 incoming from the front end)
var mySingleFileMd5 = []; MD5 function getChunkMd5(file, I) {var spark = new sparkmd5.arrayBuffer (); var fileReader = new FileReader(); fileReader.onload = function (e) { spark.append(e.target.result); mySingleFileMd5[i] = spark.end(); // Save MD5 for each slice console.log(" MD5 array for all slices =", mySingleFileMd5); } fileReader.onerror = function () { console.warn('oops, something went wrong'); } function loadNext() { fileReader.readAsArrayBuffer(blobSlice.call(file, 0, file.size)); } loadNext(); }Copy the code
After calling interface A, the PARTINDEX is obtained (uploading starts from the number of slices), and then interface B is called for uploading. After uploading, the progress is calculated manually.
Parameter transfer and parameter retrieval are as follows:
var params = {
serviceid: 'wcm61_bigfile'.methodname: 'startUpload'.fileName: Mobile QQ Video _20181212094958. Mp4,fileDigest: 65309fc9684b4eb2f3d281da5ad17b6e,
fileSize: 100904886}; {"MSG":"Operation successful"."DATA": {"TOTALPARTCOUNT":"49"."PARTINDEX":"1".// This field is the background to tell the front end from which slice to upload
"PARTSIZE":"2097152"."FLAG":"1"."FILENAME":"Mobile QQ Video _20181212094958.mp4"
},
"ISSUCCESS":"true"
}
Copy the code
B Interface parameter transfer and parameter retrieval are as follows:
var data = singleFileData[partIndex - 1] // Slice the data
varFileName = mobile QQ Video _20181212094958. Mp4;/ / file name
var fileDigest = 65309fc9684b4eb2f3d281da5ad17b6e; // MD5 of the file
var partIndex = 1; // Slice position
var partDigest = ea58e21870ad4c22f2c75645564654b2; // Slice MD5
{
"filename":"Mobile QQ Video _20181212094958.mp4"."PARTINDEX":"2".// Start passing the second slice next time
"PARTSIZE":"2097152".// Slice size
"totalPartCount":"49" // Total number of slices
"ISSUCCESS":"1"
}
Copy the code
Through interface B, slices are continuously uploaded to the server, and the upload progress is calculated in real time
var processNum =
parseInt((PARTINDEX - 1) / totalPartCount * 100) // Number of uploaded slices/total slices
Copy the code