Lire des fichiers en JavaScript

La sélection et l'interaction avec des fichiers sur l'appareil local de l'utilisateur sont l'une des les caractéristiques les plus couramment utilisées du Web. Il permet aux utilisateurs de sélectionner des fichiers et et les importer sur un serveur, par exemple lorsque vous partagez des photos ou que vous indiquez des taxes, documents. Il permet aussi aux sites de les lire et de les manipuler pour transférer les données sur le réseau. Cette page explique comment utiliser JavaScript pour interagir avec les fichiers.

API moderne File System Access

L'API File System Access permet de lire et d'écrire dans des fichiers et sur le système local de l'utilisateur. Il est disponible dans la plupart des applications comme Chrome et Edge. Pour en savoir plus, consultez L'API File System Access

L'API File System Access n'étant pas compatible avec tous les navigateurs, nous nous vous recommandons d'utiliser browser-fs-access, une bibliothèque d'assistance qui utilise la nouvelle API chaque fois qu'elle est disponible et aux anciennes approches si ce n'est pas le cas.

Travailler avec des fichiers de façon classique

Ce guide vous explique comment interagir avec des fichiers à l'aide de méthodes JavaScript anciennes.

Sélectionner des fichiers

Il existe deux méthodes principales pour sélectionner des fichiers : l'élément d'entrée HTML, et l'utilisation d'un zone de glisser-déposer.

Élément d'entrée HTML

Le moyen le plus simple pour les utilisateurs de sélectionner des fichiers consiste à utiliser <input type="file"> compatible avec tous les principaux navigateurs. Lorsque l'utilisateur clique dessus, sélectionnez un ou plusieurs fichiers multiple est inclus, en utilisant la sélection de fichiers intégrée à son système d'exploitation. UI. Lorsque l'utilisateur a terminé de sélectionner un ou plusieurs fichiers, la propriété change de l'élément se déclenche automatiquement. Vous pouvez accéder à la liste des fichiers depuis event.target.files, qui est un objet FileList. Chaque élément de FileList est un objet File.

<!-- The `multiple` attribute lets users select multiple files. -->
<input type="file" id="file-selector" multiple>
<script>
  const fileSelector = document.getElementById('file-selector');
  fileSelector.addEventListener('change', (event) => {
    const fileList = event.target.files;
    console.log(fileList);
  });
</script>

L'exemple suivant permet à un utilisateur de sélectionner plusieurs fichiers en utilisant son l'interface utilisateur intégrée de sélection de fichiers du système, puis consigne chaque fichier sélectionné dans console.

Limiter les types de fichiers que les utilisateurs peuvent sélectionner

Dans certains cas, vous pouvez limiter les types de fichiers que les utilisateurs peuvent sélectionner. Pour Par exemple, une application d'édition d'images ne doit accepter que les images, et non les fichiers texte. Pour définir des restrictions de type de fichier, ajoutez une accept à l'élément d'entrée pour spécifier les types de fichiers acceptés:

<input type="file" id="file-selector" accept=".jpg, .jpeg, .png">

Glisser-déposer personnalisé

Dans certains navigateurs, l'élément <input type="file"> est également une cible de dépôt, permettant aux utilisateurs de glisser-déposer des fichiers dans votre application. Toutefois, cette cible de baisse est petit et peut être difficile à utiliser. Au lieu de cela, après avoir fourni les fonctionnalités de base en utilisant un élément <input type="file">, vous pouvez fournir un grand format de glisser-déposer personnalisé sur la surface de l'écran.

Choisissez votre zone de dépôt

Votre surface de dépôt dépend de la conception de votre application. Vous ne voulez peut-être une partie de la fenêtre en tant que surface d'affichage, mais vous pouvez utiliser la fenêtre entière.

<ph type="x-smartling-placeholder">
</ph> Capture d&#39;écran de Squoosh, une application Web de compression d&#39;images. <ph type="x-smartling-placeholder">
</ph> Squoosh transforme toute la fenêtre en zone d'abandon.

L'application de compression d'image Squoosh permet à l'utilisateur de faire glisser une image n'importe où dans le puis cliquez sur Select an image (Sélectionner une image) pour appeler <input type="file">. . Quelle que soit la zone de dépôt que vous choisissez, assurez-vous qu'elle est claire pour l'utilisateur. de faire glisser des fichiers sur cette surface.

Définir la zone de dépôt

Pour activer un élément en tant que zone de glisser-déposer, créez des écouteurs pour Deux événements: dragover et drop. L'événement dragover met à jour l'interface utilisateur du navigateur pour indiquer visuellement que glisser-déposer crée une copie du fichier. L'événement drop se déclenche après que l'utilisateur a déposé les fichiers sur la surface. Comme pour l'élément d'entrée, peut accéder à la liste des fichiers de event.dataTransfer.files, qui est une objet FileList. Chaque élément dans FileList est un objet File.

const dropArea = document.getElementById('drop-area');

dropArea.addEventListener('dragover', (event) => {
  event.stopPropagation();
  event.preventDefault();
  // Style the drag-and-drop as a "copy file" operation.
  event.dataTransfer.dropEffect = 'copy';
});

dropArea.addEventListener('drop', (event) => {
  event.stopPropagation();
  event.preventDefault();
  const fileList = event.dataTransfer.files;
  console.log(fileList);
});

event.stopPropagation() et event.preventDefault() arrêter le comportement par défaut du navigateur et laisser votre code s'exécuter à la place. Sans eux, autrement le navigateur quitterait votre page pour ouvrir les fichiers l'utilisateur est tombé dans la fenêtre du navigateur.

Pour voir une démonstration en direct, consultez Glisser-déposer personnalisé.

Qu'en est-il des répertoires ?

Malheureusement, il n'existe aucun bon moyen d'accéder à un répertoire en utilisant JavaScript.

webkitdirectory de l'élément <input type="file"> permet à l'utilisateur de choisir un répertoire ou répertoires. Il est compatible avec la plupart des principaux navigateurs. sauf pour Firefox pour Android et Safari sur iOS.

Si le glisser-déposer est activé, un utilisateur peut essayer de faire glisser un répertoire dans dans une zone de dépôt. Lorsque l'événement "déposer" se déclenche, il inclut un objet File pour mais ne fournit aucun accès à aucun des fichiers du répertoire.

Lire les métadonnées d'un fichier

L'objet File contient des métadonnées sur le fichier. La plupart des navigateurs indiquez le nom du fichier, sa taille et le type MIME, bien que selon sur la plate-forme, différents navigateurs peuvent proposer des fonctionnalités différentes des informations.

function getMetadataForFileList(fileList) {
  for (const file of fileList) {
    // Not supported in Safari for iOS.
    const name = file.name ? file.name : 'NOT SUPPORTED';
    // Not supported in Firefox for Android or Opera for Android.
    const type = file.type ? file.type : 'NOT SUPPORTED';
    // Unknown cross-browser support.
    const size = file.size ? file.size : 'NOT SUPPORTED';
    console.log({file, name, type, size});
  }
}

Pour voir comment cela fonctionne, accédez à la page input-type-file. la démo.

Lire le contenu d'un fichier

Utilisez FileReader pour lire le contenu d'un objet File en mémoire. Vous pouvez dire à FileReader de lire un fichier en tant que tampon de tableau ; une URL de données ; ou texte:

function readImage(file) {
  // Check if the file is an image.
  if (file.type && !file.type.startsWith('image/')) {
    console.log('File is not an image.', file.type, file);
    return;
  }

  const reader = new FileReader();
  reader.addEventListener('load', (event) => {
    img.src = event.target.result;
  });
  reader.readAsDataURL(file);
}

Cet exemple lit un File fourni par l'utilisateur, puis le convertit en et utilise cette URL de données pour afficher l'image dans un élément img. Pour savoir comment vérifier que l'utilisateur a sélectionné un fichier image, consultez Démonstration de read-image-file

Surveiller la progression de la lecture d'un fichier

Lors de la lecture de fichiers volumineux, il peut être utile de fournir une certaine expérience utilisateur pour indiquer à l'utilisateur la progression de la lecture. Pour cela, utilisez la méthode progress fourni par FileReader. L'événement progress a deux propriétés: loaded (nombre de lectures) et total (nombre de lectures).

function readFile(file) {
  const reader = new FileReader();
  reader.addEventListener('load', (event) => {
    const result = event.target.result;
    // Do something with result
  });

  reader.addEventListener('progress', (event) => {
    if (event.loaded && event.total) {
      const percent = (event.loaded / event.total) * 100;
      console.log(`Progress: ${Math.round(percent)}`);
    }
  });
  reader.readAsDataURL(file);
}

Image héros de Vincent Botta, de la chaîne Unsplash