Lettura di file in JavaScript

La selezione e l'interazione con i file sul dispositivo locale dell'utente sono una delle funzioni più comunemente utilizzate del web. Consente agli utenti di selezionare file e caricarli su un server, ad esempio, quando si condividono foto o si inviano documenti. Inoltre, consente ai siti di leggerli e manipolarli senza dover per trasferire i dati attraverso la rete. Questa pagina illustra come utilizzare JavaScript per interagire con i file.

La moderna API File System Access

L'API File System Access fornisce un modo per leggere e scrivere su file e sul sistema locale dell'utente. È disponibile nella maggior parte dei come Chrome ed Edge. Per saperne di più, consulta API File System Access.

Poiché l'API File System Access non è compatibile con tutti i browser, consigliamo di utilizzare browser-fs-access, una libreria helper che utilizza la nuova API ovunque sia disponibile agli approcci legacy quando non è così.

Lavora con i file in un modo classico

Questa guida mostra come interagire con i file utilizzando i metodi JavaScript precedenti.

Seleziona file

Esistono due modi principali per selezionare i file: utilizzando l'elemento di input HTML e l'utilizzo di un zona di trascinamento.

Elemento di input HTML

Il modo più semplice per gli utenti di selezionare i file è utilizzare <input type="file"> supportato in tutti i principali browser. Se selezionato, permette a un utente seleziona uno o più file, se multiple utilizzando la selezione di file integrata nel sistema operativo. nell'interfaccia utente. Quando l'utente termina di selezionare uno o più file, lo change dell'elemento di eventi. Puoi accedere all'elenco di file da event.target.files, che è un oggetto FileList. Ogni elemento nell'elemento FileList è un oggetto 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'esempio seguente consente a un utente di selezionare più file utilizzando il proprio sistema operativo all'interfaccia utente integrata di selezione dei file nel sistema, quindi registra ogni file selezionato nel Google Cloud.

Limita i tipi di file che gli utenti possono selezionare

In alcuni casi, è consigliabile limitare i tipi di file che gli utenti possono selezionare. Per Ad esempio, un'app di modifica delle immagini dovrebbe accettare solo immagini, non file di testo. Per impostare restrizioni sui tipi di file, aggiungi accept all'elemento di input per specificare quali tipi di file sono accettati:

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

Trascinamento personalizzato

In alcuni browser, anche l'elemento <input type="file"> è un drop target, consentendo agli utenti di trascinare file nella tua app. Tuttavia, questo calo target è piccolo e può essere difficile da usare. Al contrario, dopo aver fornito le funzionalità di base utilizzando un elemento <input type="file">, puoi fornire un trascinamento personalizzato di grandi dimensioni superficie.

Scegli la tua zona di rilascio

La superficie di rilascio dipende dalla progettazione dell'applicazione. Potresti volere solo parte della finestra come superficie di rilascio, ma puoi utilizzare l'intera finestra.

Uno screenshot di Squoosh, un&#39;app web per la compressione di immagini.
. Squoosh trasforma l'intera finestra in una zona di lancio.

L'app di compressione delle immagini Squoosh consente all'utente di trascinare un'immagine in qualsiasi punto e fai clic su Seleziona un'immagine per richiamare la finestra <input type="file"> . Qualunque sia la tua zona di rilascio, assicurati che sia chiara all'utente in modo da poter trascinare i file su quella piattaforma.

Definisci la zona di rilascio

Per abilitare un elemento come zona di trascinamento, crea listener per due eventi: dragover e drop. L'evento dragover aggiorna l'interfaccia utente del browser per indicare visivamente che di trascinamento è la creazione di una copia del file. Viene attivato l'evento drop dopo che l'utente ha rilasciato i file sulla piattaforma. Come per l'elemento di input, può accedere all'elenco di file da event.dataTransfer.files, che è una FileList. Ciascuna L'elemento in FileList è un oggetto 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() e event.preventDefault() il comportamento predefinito del browser e l'esecuzione del codice. Senza di essi, il browser abbandonerebbe la pagina e aprirà i file l'utente ha raggiunto la finestra del browser.

Per una dimostrazione dal vivo, consulta l'articolo Trascinamento personalizzato.

E le directory?

Purtroppo, non c'è un buon modo per accedere a una directory utilizzando JavaScript.

La webkitdirectory nell'elemento <input type="file"> consente all'utente di scegliere una directory o directory. È supportato nella maggior parte dei principali browser ad eccezione di Firefox per Android e Safari su iOS.

Se il trascinamento è abilitato, un utente potrebbe provare a trascinare una directory la zona di caduta. Quando si attiva l'evento di rilascio, include un oggetto File per il parametro ma non fornisce l'accesso a nessuno dei file al suo interno.

Leggi i metadati dei file

L'oggetto File contiene metadati relativi al file. La maggior parte dei browser specificare il nome file, le dimensioni del file e il tipo MIME, sebbene a seconda sulla piattaforma, browser diversi possono offrire informazioni.

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});
  }
}

Puoi vedere come funziona nel input-type-file demo.

Leggere i contenuti di un file

Utilizza FileReader per per leggere in memoria il contenuto di un oggetto File. Puoi dire a FileReader di legge un file come buffer di array un URL di dati, o testo:

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);
}

Questo esempio legge un valore File fornito dall'utente e poi lo converte in un valore di dati dest. e utilizza l'URL di dati per visualizzare l'immagine in un elemento img. Per scoprire come verificare che l'utente abbia selezionato un file immagine, consulta la Demo di read-image-file.

Monitora l'avanzamento della lettura di un file

Durante la lettura di file di grandi dimensioni, può essere utile fornire un po' di esperienza utente per comunicare all'utente l'avanzamento della lettura. A questo scopo, utilizza progress evento fornito da FileReader. L'evento progress ha due proprietà: loaded (importo letto) e total (importo da leggere).

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);
}

Immagine hero di Vincent Botta da Unsplash