W3docs

File API

La File API in JavaScript consente agli sviluppatori web di interagire con i file lato client, permettendo agli utenti di selezionare, leggere e manipolare file nelle applicazioni web.

File API in JavaScript: Interagire con i File degli Utenti

La File API in JavaScript è uno strumento potente che consente agli sviluppatori web di interagire con i file lato client, permettendo agli utenti di selezionare, leggere e manipolare file all'interno delle applicazioni web. Questa API ha diverse applicazioni, tra cui il caricamento di file, l'elaborazione di contenuti generati dagli utenti e l'esecuzione di operazioni relative ai file. In questo articolo esploreremo cos'è la File API, i suoi vantaggi, quando utilizzarla e alcuni casi d'uso comuni.

Cos'è la File API?

La File API è una JavaScript API che fornisce accesso ai file selezionati dall'utente tramite campi di input per i file (<input type="file">) o file trascinati sulle pagine web. Espone un piccolo insieme di interfacce che lavorano insieme:

  • File — rappresenta un singolo file selezionato dall'utente. Contiene metadati come name, size (in byte), type (tipo MIME) e lastModified (un timestamp). Un File è un tipo speciale di Blob.
  • Blob — un blocco di dati binari immutabili ("Binary Large Object"). Ogni File è un Blob, ma è possibile anche creare i propri blob da scaricare o caricare. Consulta il capitolo dedicato a JavaScript Blob per ulteriori informazioni.
  • FileList — la raccolta array-like restituita da input.files. Accedila con [0] oppure iterala.
  • FileReader — un lettore asincrono che carica il contenuto di un file in memoria come testo, data URL o ArrayBuffer.

Poiché tutto ciò viene eseguito nel browser, è possibile ispezionare, validare e visualizzare in anteprima i file prima che qualcosa raggiunga un server.

La File API legge solo i file che l'utente ti fornisce esplicitamente. Una pagina non può mai aprire silenziosamente file arbitrari dal disco del visitatore — si tratta di un confine di sicurezza deliberato.

Metodi di lettura in sintesi

FileReader espone quattro metodi di lettura. Scegli quello che corrisponde al tipo di risultato desiderato:

MetodoTipo di risultatoUtilizzo tipico
readAsText(file)string.txt, .csv, .json, codice sorgente
readAsDataURL(file)string URL data:anteprime di immagini/audio/video tramite src
readAsArrayBuffer(file)ArrayBufferanalisi binaria, hashing, ispezione di byte
readAsBinaryString(file)string di bytelegacy; preferire readAsArrayBuffer

I browser moderni espongono anche scorciatoie basate su promise direttamente sul blob: await file.text(), await file.arrayBuffer() e file.stream(). Questi spesso sostituiscono FileReader nel nuovo codice e si abbinano naturalmente ad async/await.

Quando usare la File API

La File API è particolarmente utile quando si desidera:

  1. Gestire caricamenti di file — consentire agli utenti di selezionare e inviare file dai propri dispositivi.
  2. Visualizzare anteprime dei file — mostrare una miniatura dell'immagine scelta, o il testo di un documento, prima del caricamento.
  3. Validare lato client — rifiutare il tipo MIME errato o un file troppo grande prima di sprecare larghezza di banda in un caricamento.
  4. Manipolare i file localmente — ritagliare immagini, modificare testo o analizzare CSV senza un round trip al server.

Per i PDF si noti una limitazione: la File API non genera PDF. Consente solo di selezionare, leggere e salvare file. Per creare un PDF è necessaria una libreria come jsPDF, e la File API (tramite un Blob) può poi avviare il download.

Esempio di base: Lettura del contenuto di un file

Ecco un semplice esempio che utilizza la File API in JavaScript per leggere un file di testo selezionato dall'utente e visualizzarne il contenuto. Questa demo ti aiuterà a capire come interagire con i file sui tuoi dispositivi usando le tecnologie web.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>File Reader Example</title>
  </head>
  <body>
    <h1>Read Text File</h1>
    <p>First, choose a text file, then click the 'Read File' button to see your file's contents.</p>
    <input type="file" id="fileInput" accept=".txt" />
    <button onclick="readFile()">Read File</button>
    <pre id="fileContents"></pre>

    <script>
      function readFile() {
        const fileInput = document.getElementById("fileInput");
        const file = fileInput.files[0]; // Get the first file selected by the user

        if (file) {
          const reader = new FileReader();

          reader.onload = function (e) {
            const contents = e.target.result;
            document.getElementById("fileContents").textContent = contents;
          };

          reader.onerror = function (e) {
            console.error("Error reading file:", e.target.error.message);
          };

          reader.readAsText(file); // Read the file as text
        } else {
          alert("Please select a file.");
        }
      }
    </script>
  </body>
</html>

In questo codice:

  • Selezione del file: L'utente seleziona un file di testo (un file con estensione .txt) utilizzando l'elemento di input per i file.
  • Lettura del file: Quando l'utente fa clic sul pulsante "Read File", il file selezionato viene letto come testo. Da notare che le operazioni con FileReader sono asincrone; il callback onload viene eseguito solo dopo che il file è stato completamente letto.
  • Visualizzazione del file: Il contenuto del file viene mostrato in un elemento <pre>, preservando la formattazione del file di testo.

Questo esempio fornisce una dimostrazione semplice della capacità della File API di leggere e interagire con i file selezionati dall'utente in un'applicazione web.

Ispezione dei metadati di un file

Spesso è necessario conoscere i dettagli di un file prima di fare qualsiasi altra cosa — per validarlo o per mostrare all'utente cosa ha selezionato. Ogni oggetto File espone questi metadati in modo sincrono, senza necessità di lettura:

const file = fileInput.files[0];

console.log(file.name);          // e.g. "report.pdf"
console.log(file.type);          // MIME type, e.g. "application/pdf"
console.log(file.size);          // size in bytes, e.g. 12048
console.log(file.lastModified);  // ms since the Unix epoch

Un'operazione comune è convertire il conteggio dei byte in qualcosa di leggibile dall'utente:

function formatBytes(bytes) {
  if (bytes === 0) return "0 B";
  const units = ["B", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(1024));
  return (bytes / Math.pow(1024, i)).toFixed(1) + " " + units[i];
}

console.log(formatBytes(0));        // "0 B"
console.log(formatBytes(900));      // "900.0 B"
console.log(formatBytes(2048));     // "2.0 KB"
console.log(formatBytes(5242880));  // "5.0 MB"

Validazione dei file prima del caricamento

La validazione lato client fornisce all'utente un feedback immediato e risparmia un caricamento inutile. Esegui sempre la validazione anche sul server — i controlli lato client sono una comodità, non una garanzia di sicurezza, poiché chiunque può aggirarli.

function validateImage(file) {
  const allowedTypes = ["image/png", "image/jpeg", "image/webp"];
  const maxSize = 2 * 1024 * 1024; // 2 MB

  if (!allowedTypes.includes(file.type)) {
    return "Only PNG, JPEG, or WebP images are allowed.";
  }
  if (file.size > maxSize) {
    return "File is too large (max 2 MB).";
  }
  return null; // null means "valid"
}

// Simulate two checks:
console.log(validateImage({ type: "image/gif", size: 1000 }));
// "Only PNG, JPEG, or WebP images are allowed."
console.log(validateImage({ type: "image/png", size: 500 }));
// null

Anteprima di un'immagine prima del caricamento

Per mostrare una miniatura dell'immagine scelta, leggila come data URL e assegna quella string all'attributo src di un elemento <img>. Il browser decodifica direttamente il payload base64 — nessun server coinvolto.

<input type="file" id="imageInput" accept="image/*" />
<img id="preview" alt="Preview" width="200" />

<script>
  const input = document.getElementById("imageInput");
  const preview = document.getElementById("preview");

  input.addEventListener("change", () => {
    const file = input.files[0];
    if (!file) return;

    const reader = new FileReader();
    reader.onload = (e) => {
      preview.src = e.target.result; // a "data:image/...;base64,..." URL
    };
    reader.readAsDataURL(file);
  });
</script>

Per file multimediali di grandi dimensioni, preferisci URL.createObjectURL(file) invece di una data URL — restituisce un breve riferimento blob: senza copiare l'intero file in una string. Ricorda di chiamare URL.revokeObjectURL() quando l'anteprima non è più necessaria, in modo che il browser possa liberare la memoria.

Lettura di un file con le Promise moderne

Nei browser attuali puoi saltare del tutto FileReader e usare await sui metodi del blob stesso. Questo approccio è più pulito quando ci si trova già all'interno di una funzione async:

async function readTextFile(file) {
  const text = await file.text();
  return text.trim().split("\n").length; // count of lines
}

// Simulate a File with the same API as the real Blob:
const fakeFile = new Blob(["line 1\nline 2\nline 3"]);
readTextFile(fakeFile).then((lines) => console.log(lines)); // 3

Caricamento di un file su un server

Una volta selezionato un file, puoi inviarlo con fetch e un body FormData. Il browser imposta automaticamente gli header multipart/form-data corretti — non impostare Content-Type manualmente:

async function uploadFile(file) {
  const formData = new FormData();
  formData.append("upload", file, file.name);

  const response = await fetch("/api/upload", {
    method: "POST",
    body: formData,
  });
  return response.ok;
}

Consulta il capitolo sulla Fetch API per il modello completo di richiesta/risposta.

Problemi comuni

  • FileReader è asincrono. Il risultato è disponibile solo all'interno di onload; leggere reader.result alla riga successiva restituisce null.
  • input.files può contenere più file. Aggiungi l'attributo multiple all'input e itera il FileList; altrimenti vedrai sempre solo files[0].
  • Il value si azzera all'annullamento in alcuni browser. Ri-selezionare lo stesso file potrebbe non attivare change; reimposta prima input.value = "" se devi rilevarlo.
  • file.type può essere vuoto. Per le estensioni sconosciute il tipo MIME potrebbe essere ""; non fare mai affidamento su di esso come unico controllo.
  • Gli URL degli object perdono memoria. Ogni URL.createObjectURL() deve essere abbinato a un URL.revokeObjectURL().

Conclusione

La File API in JavaScript permette agli sviluppatori web di lavorare con i file degli utenti direttamente all'interno delle applicazioni web, aprendo possibilità per migliorare le interazioni degli utenti e offrire un'esperienza d'uso fluida. Che tu stia costruendo un caricatore di file, un editor di documenti o qualsiasi applicazione che richieda la manipolazione di file, la File API ti fornisce gli strumenti per creare soluzioni di gestione dei file lato client ricche di funzionalità.

Per approfondire, esplora il capitolo su JavaScript Blob per costruire e scaricare dati binari personalizzati, Drag and Drop con JavaScript per consentire agli utenti di trascinare file sulla pagina, e la Fetch API per inviare file a un server.

Esercitazione

Pratica
Cosa puoi fare con la File API in JavaScript?
Cosa puoi fare con la File API in JavaScript?
Was this page helpful?