Get started with 33% off your first certification using code: 33OFFNEW

Uploading Large Files with Chunking in JavaScript

3 min read
Published on 27th June 2023

In the era of high-speed internet, uploading large files seems like a non-issue. However, users with unstable connections still encounter difficulties when trying to upload large files. The upload might fail midway due to the instability of the connection, leading to time and bandwidth wastage as the entire process needs to start anew. One practical solution to this issue is to implement chunking, where large files are divided into smaller parts and uploaded one at a time. This article guides you through the process of implementing this solution in JavaScript on the client side.

Understanding File Chunking

File chunking refers to the process of splitting a large file into smaller pieces, often referred to as 'chunks.' These chunks are then uploaded separately. This process is particularly useful when dealing with unstable network connections because if the upload of one chunk fails, it can be reattempted without needing to re-upload the previously uploaded chunks.

Implementing File Chunking in JavaScript

In JavaScript, the Blob object's slice method allows us to implement file chunking. The slice method can be used to create a new Blob that contains data from the original Blob within specified start and end points.

Consider a scenario where we're trying to upload a video file. The basic process is as follows:

  1. Select a file using an HTML input element.
  2. Use JavaScript to slice the file into chunks.
  3. Send the chunks to the server one by one.

Here's a code snippet to illustrate these steps:

// HTML input element
<input type="file" id="file-upload">

// JavaScript file handling
const fileInput = document.getElementById('file-upload');
fileInput.addEventListener('change', handleFileUpload);

function handleFileUpload(event) {
  const file = event.target.files[0];
  const chunkSize = 1024 * 1024; // size of each chunk (1MB)
  let start = 0;

  while (start < file.size) {
    uploadChunk(file.slice(start, start + chunkSize));
    start += chunkSize;
  }
}

function uploadChunk(chunk) {
  const formData = new FormData();
  formData.append('file', chunk);

  // Make a request to the server
  fetch('/upload-endpoint', {
    method: 'POST',
    body: formData,
  });
}

In the example above, we first select a file using an HTML input element. Then, we add an event listener to the input element that triggers the handleFileUpload function whenever a file is selected. This function slices the selected file into chunks and uploads each chunk to the server.

Error Handling and Retry Mechanism

With unstable connections, some of the upload requests might fail. Therefore, we need a mechanism to handle these failures. We could modify our uploadChunk function to retry the request a certain number of times before ultimately failing:

async function uploadChunk(chunk, retries = 3) {
  const formData = new FormData();
  formData.append('file', chunk);

  try {
    await fetch('/upload-endpoint', {
      method: 'POST',
      body: formData,
    });
  } catch (error) {
    if (retries > 0) {
      await uploadChunk(chunk, retries - 1);
    } else {
      console.error('Failed to upload chunk: ', error);
    }
  }
}

In this version of uploadChunk, we wrap our fetch request in a try-catch block. If the request fails, we catch the error and retry the request. We keep track of the number of retries and only fail after the specified number of retries has been exhausted.

In summary, file chunking can significantly improve the user experience when uploading large files over unstable connections. This approach can prevent unnecessary bandwidth usage and save time by ensuring that a temporary failure doesn't require re-uploading the entire file. With the concepts and examples discussed in this guide, you should now be well-equipped to implement this feature in JavaScript on the client side.