js resumable upload, combined with php backend

I found a case on the Internet to solve the problem of uploading files that are too large and failing in the project. It can be solved by resuming transmission with a breakpoint. Record it, it won’t be found after saving;

Source address:https://download.csdn.net/download/weixin_43996999/12760387

The downloaded file needs to be run with the php environment, because the back-end processing method is written by php, here is recommended to use wampserver, please see another article for detailed usage:
https://blog.csdn.net/weixin_43996999/article/details/108201663

Use JS to realize a file upload scheme that can be resumed

When I first started learning front-end development, I encountered file upload problems, and I also requested that the upload can be resumed. I checked a lot of information and found that H5's file API can just meet our needs, and some problems have been encountered, so I recorded it and provided some help to friends with the same needs.

1. First, in order to import a file object, an input tag of file type needs to be placed on the H5 page.

<input type="file" id="file" onchange="fileInfo()">

When the file is selected, the related information of the file is displayed:

 function fileInfo() {
    
    
     let fileObj = document.getElementById('file').files[0];
     console.log(fileObj);
 }

The object we get is an array itself. Only one file is selected here. If multiple files need to be selected, the multiple attribute can be added to the input tag. Now we open the browser console and we can see that the last modification time, file size, and file name of the file are output:

2. Okay, when we get the selected file object, now we need to upload the file to the server, we can simulate the form event to upload, we need to introduce the FormData object, and secondly, due to the HTTP limit on the file upload size, so we need to upload the file Upload in chunks. After the server receives the file chunks, it will be spliced ​​into a whole. Finally, a progress bar is needed to display the upload progress. After clarifying the ideas, this will be realized by hands:

First place a progress bar on the H5 page, and at the same time replace the selected file change event with the upload file block function upload (start uploading bytes), here we start uploading from the 0th byte, that is, start uploading from the beginning:

<input type="file" id="file" onchange="upload(0)">
<progress id="progress" max="100" value="0"></progress>

Then to implement the upload function of the file block:

 1 // 文件切块大小为1MB
 2 const chunkSize = 1024 * 1024;
 3 
 4 // 从start字节处开始上传
 5 function upload(start) {
    
    
 6     let fileObj = document.getElementById('file').files[0];
 7     // 上传完成
 8     if (start >= fileObj.size) {
    
    
 9         return;
10     }
11     // 获取文件块的终止字节
12     let end = (start + chunkSize > fileObj.size) ? fileObj.size : (start + chunkSize);
13     // 将文件切块上传
14     let fd = new FormData();
15     fd.append('file', fileObj.slice(start, end));
16     // POST表单数据
17     let xhr = new XMLHttpRequest();
18     xhr.open('post', 'upload.php', true);
19     xhr.onload = function() {
    
    
20         if (this.readyState == 4 && this.status == 200) {
    
    
21             // 上传一块完成后修改进度条信息,然后上传下一块
22             let progress = document.getElementById('progress');
23             progress.max = fileObj.size;
24             progress.value = end;
25             upload(end);
26         }
27     }
28     xhr.send(fd);
29 }

Here, the native JS is used to send a request to the server, the file is sliced ​​into pieces using the function slice (start position, end position), and then the file block is encapsulated in the FormData object to realize the file upload of the simulated form. I use PHP to receive data in the backend, or other backend languages:

1 <?php
2     // 追加文件块
3     $fileName = $_FILES['file']['name'];
4     file_put_contents('files/' . $fileName, file_get_contents($_FILES['file']['tmp_name']), FILE_APPEND);
5 ?>

Here I created a new folder files, and store the uploaded files here. The content of the obtained file block adopts the appended form FILE_APPEND. So we open the browser to upload the file:

Then check whether the vscode.exe file is received under the files folder:

Third, with the file upload function, we need to implement the breakpoint resume function. On the basis of the file block in the previous step, the resumable upload becomes very simple. If the Internet is suddenly disconnected or the browser is closed unexpectedly, then the uploaded file is incomplete. We only need to check the server after selecting the file. The size of the same file name on the server, and then set the starting upload position (bytes) to this size:

First define an initialization function. After selecting a file, query the server for the size of the uploaded file:

1 // 初始化上传大小
 2 function init() {
    
    
 3     let fileObj = document.getElementById('file').files[0];
 4     let xhr = new XMLHttpRequest();
 5     xhr.onreadystatechange = function() {
    
    
 6         if (this.readyState == 4 && this.status == 200) {
    
    
 7             // 将字符串转化为整数
 8             let start = parseInt(this.responseText);
 9             // 设置进度条
10             let progress = document.getElementById('progress');
11             progress.max = fileObj.size;
12             progress.value = start;
13             // 开始上传
14             upload(start);
15         }
16     }
17     xhr.open('post', 'fileSize.php', true);
18     // 向服务器发送文件名查询大小
19     xhr.send(fileObj.name);
20 }

Use fileSize.php on the server to query the size of the uploaded file:

 1 <?php
 2     // 接收文件名
 3     $fileName = $_GET['fileName'] ? $_GET['fileName'] : '';
 4     $fileSize = 0;
 5     $path = 'files/' . $fileName;
 6     //查询已上传文件大小
 7     if (file_exists($path)) {
    
    
 8         $fileSize = filesize($path);
 9     }
10     echo $fileSize;
11 ?>

Finally, change the onchange event of the input tag on the H5 page to init():

<input type="file" id="file" onchange="init()">

At the same time, the upload function does not need to repeatedly set the maximum value of the progress bar, modified to:

1 // 上传一块完成后修改进度条信息,然后上传下一块
2 document.getElementById('progress').value = end;
3 upload(end);

Then open the browser and deliberately close the browser during the upload process and you can resume the upload from the breakpoint next time you select the same file.

Fourth, although the file upload function that can be resumed at a breakpoint has been implemented, the interface needs to be beautified. The bootstrap framework is referenced here, and jquery is needed. By the way, jquery ajax is used instead of native JS ajax. Note that $.ajax Both the processData and contentType attributes must be set to false:

 1 // POST表单数据
 2 $.ajax({
    
    
 3     url: 'upload.php',
 4     type: 'post',
 5     data: fd,
 6     processData: false,
 7     contentType: false,
 8     success: function() {
    
    
 9         upload(end);
10     }
11 });

The final rendering of beautification is as follows:
Insert picture description here
Reposted from: https://www.cnblogs.com/viewts/p/10820785.html

Guess you like

Origin blog.csdn.net/weixin_43996999/article/details/108256158