Resumable Chunk Upload

JavaScript
Resumable Chunk Upload - Banner

Uploader un gros fichier en une seule requête, c'est risqué : si ça coupe, on recommence depuis zéro. Le chunk upload divise le fichier en petits morceaux uploadés individuellement. Si ça échoue, on reprend là où on s'est arrêté.

Resumable Chunk Upload est une implémentation de cette technique. Simple à configurer, elle expose la progression, le temps restant, et gère la reprise automatique.

Installation

Installation avec un gestionnaire de paquets:

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 requises avant de lancer l'upload avec la méthode upload:

  • Cré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.