嘿, 我是Mofei!
HTML5 File API Implementation of Resumable Uploads

Currently, most websites on the market require browser plugins for resumable uploads. This article explains how to implement resumable uploads using the HTML5 File API under advanced browser environments.

1. Implementing Multiple File Selection

The HTML5 <input> has added the "multiple" attribute, which allows for multiple file uploads in a single input field.

<input type="file" multiple="multiple" name="file" id="file">

With this attribute, users can now select multiple files at once in the pop-up dialog.

2. Implementing File Drag and Drop Functionality and Adding File Queue

We use the dragover and drop events to manage the file drag-and-drop functionality.

The dragover event handles the action when moving over a specified element. Here, we bind the dragover event to the body to handle file dragging events in the page.

document.body.addEventListener('dragover', dragFile, false);

function dragFile(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    evt.dataTransfer.dropEffect = 'copy';
}

We use the drop event to handle the action when the mouse is released; at this point, we should add the dragged files to the upload queue for subsequent processing.

document.body.addEventListener('drop', dropFile, false);

function dropFile(evt) {
    evt.stopPropagation();
    evt.preventDefault();
    // The dataTransfer.files property can access all selected dragged files. You can iterate through to read all file information.
    // Iterating through each file allows you to get essential information like name, size, type, lastModifiedDate, etc.
    var files = evt.dataTransfer.files;
    // addfile method is used to add the upload file queue. This needs to be called also in the change event of input.
    // This method first checks if any files are currently uploading. If there are, it adds the subsequent files to the upload queue; if not, it executes the upload command directly.
    addfile(files);
}

3. Resumable Upload Principle

Currently, there are two commonly used methods for resumable uploads: one is through WebSocket interfaces for file uploads, and the other is via AJAX. Both methods have their pros and cons; while WebSocket may sound more sophisticated, the underlying algorithms are quite similar, and the server must open the WebSocket interface. Here, we will explain the resumable upload concept using the relatively convenient AJAX.

In essence, the core of resumable uploads is to "slice" the file and then send each slice to the server. However, this seemingly simple upload process has countless pitfalls.

The first issue is file identification. Once a file is split into several pieces, how to inform the server of how many pieces you've created and how the server should merge the uploaded parts is crucial.

Thus, before starting the upload, we need a "handshake" process with the server, informing it of the file information and agreeing on the slice size. Once we reach consensus with the server, we can begin subsequent file transfers.

Each piece of the file must be sent to the back end, and upon successful transmission, both the front end and back end need to mark it for future resumability.

When the upload is interrupted, and the user selects the file again, we can check the tags to determine whether any part of the file has already been uploaded. If so, we can continue uploading from the previous position to achieve the resumable upload functionality.

4. Frontend File Slicing

With HTML5's File API, slicing files is significantly simpler than one might imagine.

All it takes is the slice method.

var packet = file.slice(start, end);

The start parameter is the position where the slicing begins, and the end is the position where the slicing ends, both measured in bytes. By controlling start and end, we can achieve file chunking.

For example:

file.slice(0,1000);
file.slice(1000,2000);
file.slice(2000,3000);
// ......

5. Uploading File Fragments

In the previous step, we used the slice method to divide the file into several chunks; the next task is to upload these fragments to the server.

We can use AJAX's POST request for this.

var xhr = new XMLHttpRequest();
var url = xxx // The file upload URL, which can include parameters like file name, chunk number, etc., for back-end processing.
xhr.open('POST', url, true);
xhr.onload = function (e){
     // Check if the file upload succeeded; if so, continue with the next chunk; if it fails, retry that chunk.
}
xhr.upload.onprogress = function(e){
     // Optionally, if the file chunks are large, this method can be used to determine the upload progress of a single chunk.
     // e.loaded  indicates how much of the chunk has been uploaded.
     // e.totalSize  indicates the total size of the chunk.
}
xhr.send(packet);
THE END

More Articles You Might Be Interested In

Did this post inspire any ideas? Share your thoughts in the comments!

avatar

Mofei's Friend (Click to edit)

Hey, say something!

HI. I AM MOFEI!

NICE TO MEET YOU!