HTML5 solves the problem of resuming upload of large files at breakpoints

1. Use the file api to “slice” the file, and use slice to resume the upload idea: The core content of the resume upload is to “slice” the file and then pass it to the server piece by piece, but this seems to be a simple upload process. But there are countless pitfalls. The first is file identification. After a file is divided into several parts, how to tell the server how many pieces you have cut, and finally how the server should merge the files you uploaded, all need to be considered. Therefore, before the file starts to be uploaded, we need to have a “handshake” process with the server, tell the server the file information, and then agree on the size of the slice with the server. After reaching a consensus with the server, we can start subsequent file transfers. The front end must pass each piece of file to the back end. After success, both the front end and the back end must be marked for subsequent breakpoints. When the file transfer is interrupted, the user can select the file again and use the logo to determine whether part of the file has been uploaded. If so, then we can continue to upload the file according to the last progress to achieve the function of resuming the upload.
Front-end slicing of files With the File api of HTML5, cutting files is much simpler than imagined. Just use the slice method

var packet = file.slice(start, end); The parameter start is the position where the slice starts, and end is the position where the slice ends. The units are all bytes.
By controlling start and end, you can implement file segmentation, such as 1. file.slice(0,1000);

file.slice(1000,2000);
file.slice(2000,3000);
2. HTML5 FormData implementation of file upload example Form submission and file upload are a commonly used and very troublesome function. In the past, uploading files was usually achieved with the help of plug-ins or flash, which loaded a lot of things. Since the introduction of HTML5’s FormData, my boss no longer has to worry about my uploading. FormData can be understood as a virtual form object. It has only one method append, which can be found out through the browser console. We can add various data that need to be submitted to FormData through append. You can first create an empty FormData object, and then use the append() method to add fields to the object.
as follows:

var oMyForm = new FormData();
oMyForm.append("username", "Groucho");
oMyForm.append("accountnum", 123456); // The number 123456 is immediately converted into the string "123456"

// fileInputElement already contains the file selected by the user

oMyForm.append("userfile", fileInputElement.files[0]);
var oReq = new XMLHttpRequest();
oReq.open("POST", "http://foo.com/submitform.php");
oReq.send(oMyForm);

The FormData object allows us to organize a collection of key-value pairs sent using the XMLHttpRequest object. It is mainly used for sending form data, but can be used independently of the data transferred using the form. Sending files using the FormData object You can also add a File or Blob directly to the FormData object, like this:

 data.append("myfile", myBlob, "filename.txt");

When using the append() method, the third parameter may be used to send the file name (sent to the server through the ContentDisposition header). If the third parameter is not specified or is not supported, the third parameter defaults to “blob”.

js code

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>xhr2</title>
</head>
<body>
<div id="drop_area" style="border:3px dashed silver;width:200px; height:200px">
Drag the image here
</div>
\t
<progress value="0" max="10" id="prouploadfile"></progress>
\t
<span id="persent">0%</span>
<br />
<!--<button onclick="xhr2()">ajax upload</button>-->
<button onclick="stopup()" id="stop">Upload</button>
<script>
//Drag and drop upload starts
//-1. Prohibit the browser from opening files
document.addEventListener("drop",function(e){<!-- --> //Drag away
e.preventDefault();
})
document.addEventListener("dragleave",function(e){<!-- --> //Drag and drop
e.preventDefault();
})
document.addEventListener("dragenter",function(e){<!-- --> //Drag into
e.preventDefault();
})
document.addEventListener("dragover",function(e){<!-- --> //Drag around
e.preventDefault();
})
//upload progress
var pro = document.getElementById('prouploadfile');
var persistent = document.getElementById('persent');
function clearpro(){<!-- -->
pro.value=0;
present.innerHTML="0%";
}
\t
//2.Drag and drop
var stopbutton = document.getElementById('stop');
\t
var resultfile=""
var box = document.getElementById('drop_area'); //Drag area
box.addEventListener("drop",function(e){<!-- -->
var fileList = e.dataTransfer.files; //Get file object
console.log(fileList)
//Detect whether it is an operation of dragging files to the page
if(fileList.length == 0){<!-- -->
return false;
}
//Drag the image to the browser to implement the preview function
//Specify video format
//in_array
Array.prototype.S=String.fromCharCode(2);
Array.prototype.in_array=function(e){<!-- -->
var r=new RegExp(this.S + e + this.S);
return (r.test(this.S + this.join(this.S) + this.S));
};
var video_type=["video/mp4","video/ogg"];
\t\t
//Create a url connection for reference by src attribute
var fileurl = window.URL.createObjectURL(fileList[0]);
if(fileList[0].type.indexOf('image') === 0){<!-- --> //If it is a picture
var str="<img width='200px' height='200px' src='" + fileurl + "'>";
document.getElementById('drop_area').innerHTML=str;
}else if(video_type.in_array(fileList[0].type)){<!-- --> //If it is a video in the specified format
var str="<video width='200px' height='200px' controls='controls' src='" + fileurl + "'></video>";
document.getElementById('drop_area').innerHTML=str;
}else{<!-- --> //Other formats, output file name
//alert("No preview");
var str="File name:" + fileList[0].name;
document.getElementById('drop_area').innerHTML=str;
}
resultfile = fileList[0];
console.log(resultfile);
\t\t
//Slice calculation
filesize= resultfile.size;
setsize=500*1024;
filecount = filesize/setsize;
//console.log(filecount)
//Define progress bar
pro.max=parseInt(Math.ceil(filecount));
\t\t
\t\t
\t\t
i =getCookie(resultfile.name);
i = (i!=null & amp; & amp; i!="")?parseInt(i):0
\t\t
if(Math.floor(filecount)<i){<!-- -->
alert("Completed");
pro.value=i + 1;
present.innerHTML="100%";
\t\t
}else{<!-- -->
alert(i);
pro.value=i;
p=parseInt(i)*100/Math.ceil(filecount)
present.innerHTML=parseInt(p) + "%";
}
\t\t
},false);
\t
//3.ajax upload

var stop=1;
function xhr2(){<!-- -->
if(stop==1){<!-- -->
return false;
}
if(resultfile==""){<!-- -->
alert("Please select a file")
return false;
}
i=getCookie(resultfile.name);
console.log(i)
i = (i!=null & amp; & amp; i!="")?parseInt(i):0
\t\t
if(Math.floor(filecount)<parseInt(i)){<!-- -->
alert("Completed");
return false;
}else{<!-- -->
//alert(i)
}
var xhr = new XMLHttpRequest();//The first step
//Create a new FormData object
var formData = new FormData(); // + + + + + + + + + +
//Append file data
\t\t
//Change the progress bar
pro.value=i + 1;
p=parseInt(i + 1)*100/Math.ceil(filecount)
present.innerHTML=parseInt(p) + "%";
\t\t//progress bar
\t\t
\t\t
if((filesize-i*setsize)>setsize){<!-- -->
blobfile= resultfile.slice(i*setsize,(i + 1)*setsize);
}else{<!-- -->
blobfile= resultfile.slice(i*setsize,filesize);
formData.append('lastone', Math.floor(filecount));
}
formData.append('file', blobfile);
//return false;
formData.append('blobname', i); // + + + + + + + + + +
formData.append('filename', resultfile.name); // + + + + + + + + +
//post method
xhr.open('POST', 'xhr2.php'); //Second step
\t\t\t//send request
xhr.send(formData); //The third step
stopbutton.innerHTML = "Pause"
//ajax returns
xhr.onreadystatechange = function(){<!-- --> //Step 4
  if ( xhr.readyState == 4 & amp; & amp; xhr.status == 200 ) {<!-- -->
console.log(xhr.responseText);
if(i<filecount){<!-- -->
xhr2();
}else{<!-- -->
i=0;
}
  }
};
//Set the timeout
xhr.timeout = 20000;
xhr.ontimeout = function(event){<!-- -->
alert('Request timed out, network congestion! Less than 25K/s');
}
\t\t\t
i=i + 1;
setCookie(resultfile.name,i,365)
\t\t\t
}
\t
//Set cookie
function setCookie(c_name,value,expiredays)
{<!-- -->
var exdate=new Date()
exdate.setDate(exdate.getDate() + expiredays)
document.cookie=c_name + "=" + escape(value) +
((expiredays==null) ? "" : ";expires=" + exdate.toGMTString() + ";path=/")
}
//Get cookies
function getCookie(c_name)
{<!-- -->
if (document.cookie.length>0)
{<!-- -->
c_start=document.cookie.indexOf(c_name + "=")
if (c_start!=-1)
{<!-- -->
c_start=c_start + c_name.length + 1
c_end=document.cookie.indexOf(";",c_start)
if (c_end==-1) c_end=document.cookie.length
return unescape(document.cookie.substring(c_start,c_end))
}
}
return ""
}
\t
\t
function stopup(){<!-- -->
if(stop==1){<!-- -->
stop=0
\t\t\t
xhr2();
}else{<!-- -->
stop=1
stopbutton.innerHTML = "Continue"
\t\t\t
}
\t\t
}
</script>
</body>

php code

<?php
//$name=$_POST['username'];
$dir=$_POST['filename'];
$dir="uploads/".md5($dir);
file_exists($dir) or mkdir($dir,0777,true);
 
 
$path=$dir."/".$_POST['blobname'];
 
 
//print_r($_FILES["file"]);
move_uploaded_file($_FILES["file"]["tmp_name"],$path);
 
if(isset($_POST['lastone'])){<!-- -->
echo $_POST['lastone'];
$count=$_POST['lastone'];
\t
$fp = fopen($_POST['filename'],"abw");
for($i=0;$i<=$count;$i + + ){<!-- -->
$handle = fopen($dir."/".$i,"rb");
fwrite($fp,fread($handle,filesize($dir."/".$i)));
fclose($handle);
}
fclose($fp);
}
\t
\t
?>

Reference article: http://blog.ncmem.com/wordpress/2023/10/13/html5 Solve the problem of resuming breakpoint transfer of large files-2/
Welcome to join the group to discuss