Resumable Chunk Upload

30 mai 2022
JavaScript
Resumable Chunk Upload - Banner

Introduction

Uploader des gros fichiers n'est plus un problème grâce au système d'upload par morceaux. Le fichier est divisé en une séquence de parties pouvant être uploadées individuellement. Ceci nous donne la possibilité de continuer l'upload en ne téléversant que les restes de la partie en cas d'échec.

Resumable Chunk Upload est une implémentation de cette technique. Elle permet d'uploader des fichiers en petits morceaux. Elle offre une classe simple facile à configurer et des données pertinentes telles que la progression et le temps restant du téléchargement. Elle gère également la reprise de l'upload en cas d'échec.

Installation

Installation avec une gestionnaire de packet:

npm install resumable-chunk-upload

Inclure via CDN:

<script src="https://cdn.jsdelivr.net/npm/resumable-chunk-upload/dist/uploader.min.js"></script>

Simple usage

Créons l'interface:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Resumable chunk upload</title>
  </head>
  <body>
    <input type="file" /> <br />
    <button id="stop">Stop</button> <br />
    Progress: <span id="progress">0</span> % <br />
    Remaining: <span id="remaining">0</span> seconds <br />
    feedback: <span id="feedback"></span>
    <script src="https://cdn.jsdelivr.net/npm/resumable-chunk-upload/dist/uploader.min.js"></script>
    <script src="app.js"></script>
  </body>
</html>

Admettons qu'on commence l'upload après l'ajout du fichier, dans le fichier app.js

const inputNode = document.querySelector("input");
const progressNode = document.querySelector("#progress");
const remainingNode = document.querySelector("#remaining");
const feedbackNode = document.querySelector("#feedback");
 
const uploader = new Uploader()
  .setUploadStatusUrl("http://localhost:9000/uploadStatus")
  .setUploadUrl("http://localhost:9000/upload")
  .setChunkSize(10 ** 3)
  .onProgress((info) => {
    progressNode.innerHTML = info.percent;
    remainingNode.innerHTML = info.remaining;
  }, 1000);
 
inputNode.addEventListener("change", (e) => {
  uploader
    .setFile(e.target.files[0])
    .upload()
    .then((xhr) => {
      feedbackNode.insertAdjacentHTML(
        "beforeend",
        `success: ${JSON.stringify(xhr.response)}`
      );
    })
    .catch((error) => {
      if (error instanceof UploadError) {
        // This is a custom error to make it easier to manage
      }
      feedbackNode.insertAdjacentHTML("beforeend", `failed: ${e}`);
    });
});
 
document.querySelector("#stop").addEventListener("click", () => {
  uploader.abort();
});

Voici les étapes requis avant de lancer l'upload avec la method upload:

  • réer un uploader
  • Ajouter le fichier
  • Ajouter l'url pour récupérer le numéro du dernier morceau uploadé
  • Ajouter l'url de l'upload

Resumable Chunk Upload utilise deux API dans son système. Lorsque vous démarrez l'upload, il utilise la première API pour récupérer le numéro du dernier morceau uploadé, puis upload le reste des morceaux un par un avec la deuxième API jusqu'à la fin. Le système envoie un ID dans chaque demande pour permettre au back d'identifier l'upload.

Backend

Resumable Chunk Upload se concentre simplement sur les clients Javascript afin qu'il puisse être facilement intégré dans différents frameworks frontend. Pour le back, Vous pouvez trouver dans cette documentation OpenApi l'intégration de ces deux API. Vous pouvez aussi vous inspirer de ces exemples qui existent déjà.

Gestion des erreurs

Les erreurs sont toutes une instance de la classe UploadError pour faciliter sa gestion.

// ...
    if (error instanceof UploadError) {
        if (error.message === 'UPLOAD_ABORTED') {
            // Do something when upload is aborted
        }
    }
// ...

Note: N'hésitez pas à voir sa documentation pour voir les détails.