<input type="file">

Questa traduzione è incompleta. Aiutaci a tradurre questo articolo dall’inglese

Gli elementi <input> con type="file" danno all'utente la possibilità di scegliere uno o più file dalla memoria del proprio dispositivo. Una volta scelti, i file possono essere caricati su un server usando l'invio del modulo, oppure manipolati usando del codice JavaScript e l'API File

Value Una DOMString che rappresenta il percorso del file selezionato.
Eventi change e input
Attributi comuni supportati required
Attributi aggiuntivi accept, capture, files, multiple
Attributi IDL files e value
Interfaccia DOM

HTMLInputElement

Proprietà

Proprietà che si applicano soload elementi di tipo file

Metodi select()

Value

L'attributo value di un file contiene una DOMString che rappresenta il percorso del file selezionato. Se l'utente seleziona più di un file, l'attributo value rappresenta il primo file nella lista di quelli selezionati. Gli altri file possono essere identificati usando la proprietà HTMLInputElement.files.

Note:
  1. Se vengono selezionati più file, la stringa rappresenta il primo. JavaScript può accedere agli atri file attraverso la proprietà files dell'elemento input
  2. Se non è stato ancora selezionato nessun file, la stringa è "" (vuota)
  3. Alla stringa viene aggiunto il prefisso C:\fakepath\,  per impedire a software malevolo di intuire la struttura del filesystem dell'utente.

Attributi aggiuntivi

In aggiunta agli attributi comuni a tutti gli elementi <input>, gli input di tipo file supportano anche i seguenti: 

Attributo Descrizone
accept Uno o più Identificatori univoci del tipo di file che descrivono i tipi di file ammessi
capture La sorgente da utilizzare per catturare immagini o dati video
files Una FileList che elenca i file scelti
multiple Un valore booleano che, se presente, indica che l'utente può selezionare più di un file

accept

Il valore dell'attributo accept è una stringa che definisce i tipi di file che l'input accetta.
La stringa è un lista di Identificatori univoci del tipo di file separati da virgola. Poiché un determinato tipo di file può essere identificato in più di un modo, è utile fornire un set completo di identificatori di tipo quando sono necessari file di un determinato formato.

Per esempio, ci sono diversi modi in cui un file di Microsoft Word può essere identificato, quindi un sito che accetta file di Word dovrebbe utilizzare un input come questo:

<input type="file" id="docpicker"
  accept=".doc,.docx,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document">

capture

Il valore dell'attributo capture è una stringa che specifica quale camera utilizzare per catturare immagini o dati video, se l'attributo accept indica che l'input possa essere di uno di questi due tipi. Il valore user indica che devono essere usati il microfono e/o la camera frontali (lato utente). Il valore environment specifica che devono essere usati il microfono e/o la camera posteriori (lato ambiente). Se l'attributo manca, lo user agent è libero di scegliere quale tra i due utilizzare secodo le proprie specifiche. Se lo strumento di cattura indicato non è presente, lo user agent può far ricadere la scelta sulla propria modalità predefinita.

Note: capture originariamente era un attributo booleano che, se presente, richiedeva l'utilizzo di un dispositivo di acquisizione multimediale invece del caricamento di un file.

files

Un oggetto FileList che elenca tutti i file selezionati. Questa lista contiene al massimo un elemento, salvo che non sia stato specificato l'attributo multiple.

multiple

Quando l'attributo booleano multiple è specificato, il controllo consente di caricare più di un file.

Attributi non standard

Oltre agli atributi elencati sopra, su alcuni browser sono disponibili anche i seguenti attributi. In generale è consigliabile evitarne l'utilizzo laddove possibile, per consentire una completa funzionalità anche sui browser che non li implementano.

Attribute Description
webkitdirectory

Un valore booleano che indica se consentire o meno di poter selezionare una o più cartelle (se è presente anche l'attributo multiple)

webkitdirectory

L'attributo booleano webkitdirectory indica, se presente, che possono essere selezionate solo cartelle nell'interfaccia di selezione dell'utente. Si veda HTMLInputElement.webkitdirectory per ulteriori esempi.

Note: Anche se originariamente implementato solo per i browser basati su WebKit, l'attributo webkitdirectory è utilizzabile anche su Microsoft Edge e Firefox 50 o superiori. Comunque, anche se ha un supporto relativemente ampio, non è uno standard e dovrebbe essere evitato laddove non strettamente necessario.

Identificatori univoci del tipo di file

Un identificatore univoco del tipo di file è una stringa che descrive un tipo di file che può essere selezionato dall'utente in una elemento <input> di tipo file. Ogni identificatore univoco del tipo di file può avere una delle seguenti forme:

  • Una estensione di nomi file valida, che inizia con un carattere di punto ("."). E.g.: .jpg, .pdf o .doc.
  • Una stringa identificativa di un MIME-type, senza estensione.
  • La stringa audio/* ad indicare "qualunque file audio".
  • La stringa video/* ad indicare "qualunque file video".
  • La stringa image/* ad indicare "qualunque file immagine".

L'attributo accept assume come valore una stringa contenente uno o più di questi identificatori univoci del tipo di file, separati da virgole. Per esempio, 

The accept attribute takes as its value a string containing one or more of these unique file type specifiers, separated by commas. Per esempio, un selettore di file che necessiti di contenuto che possa essere rappresentato come un'immagine, inclusi sia i formati immagine standard che file PDF, potrebbe apparire così:

<input type="file" accept="image/*,.pdf">

Utilizzo degli input di tipo file

Un esempio base

<form method="post" enctype="multipart/form-data">
 <div>
   <label for="file">Scegli un file da caricare</label>
   <input type="file" id="file" name="file" multiple>
 </div>
 <div>
   <button>Invia</button>
 </div>
</form>

Produce l'output seguente:

Note: Puoi trovare questo esempio, in lingua inglese, anche su GitHub —  qui puoi trovarne i sorgenti i sorgenti, ed anche una una dimostrazione di funzionamento.

Indipendentemente dal sistema operativo o dal dispositivo dell'utente, il file input fornisce un bottone che apre una finestra di selezione che consente all'utente di scegliere un file.

Includendo l'attributo multiple, come mostrato di seguito, specifica che possono essere selezionati più file in un'unica istanza. L'utente può selezionare più file in un qualunque modo consentito dalla propria piattaforma (ad esempio tenendo premuto il tasto Shift o Ctrl, e quindi cliccando). Se si desidera che l'utente scelga un solo file per <input> è sufficiente omettere l'attributo multiple.

Ottenere informazioni sui file selezionati

I file selezionati sono restituiti dalla proprietà dell'elemento HTMLInputElement.files, che è un oggetto FileList contenente una lista di oggetti File. La FileList si comporta come un'array, quindi si può controllarne la proprietà length per conoscere il numero di file selezionati.

Ogni oggetto File contiene le seguenti informazioni:

name
Il nome del file
lastModified
Un numero che indica la data e l'ora dell'ultima modifica, espressa in millisecondi dalla "UNIX epoch" (1° Gennaio 1970 a mezzanotte).
lastModifiedDate
Un oggetto Date che rappresenta la data e l'ora dell'ultuima modifica. La proprietà è deprecata e non dovrebbe essere utilizzata. Al suo posto utilizzare la proprietà lastModified.
size
La dimensione del file in byte.
type
Il MIME-type del file.
webkitRelativePath
Una stringa che rappresenta il perorso del file relativo alla cartella selezionata in un appostito selettore di cartelle (i.g. un selettore di file in cui l'attributo webkitdirectory è stato impostato). Non è una proprietà standard e va utilizzata con attenzione

Note: È possibile leggere e scrivere il valore di HTMLInputElement.files in tutti i browser più recenti; in Firefox è stato in all modern browsers; su Firefox questa caratteristica è stata aggiunta di recente, nella versione 57 (si veda bug 1384030).

Limitare i tipi di file accettati

Spesso si ha la necessità che l'utente non si libero di selezionare arbitrariamente qualunque tipologia di file; quanto piuttosto consentire che possa selezionare file di un tipo specifico. Per esempio, se un file input consente agli utenti di caricare un'immagine di profilo, molto probabilmente occorrerà consentire solo il aricamento di formati immagine compatibili con il web, come JPEGPNG.

I tipi di file accettati possono essere specificati con l'attributo accept, che prende una lista di estensioni consentite o MIME-type, separate da virgola. Ecco alcuni esempi:

  • accept="image/png"accept=".png" — Accetta file PNG.
  • accept="image/png, image/jpeg"accept=".png, .jpg, .jpeg" — Accetta file PNG o JPEG.
  • accept="image/*" — Accetta qualunque file con MIME-type image/*. (Molti dispositivi mobili consentono all'utente di scattare una foto quando viene specificato questo formato)
  • accept=".doc,.docx,.xml,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document" —  accetta qualunque file che sembri un documento di MS Word.

Osserviamo un esempio più completo:

<form method="post" enctype="multipart/form-data">
  <div>
    <label for="profile_pic">Scegli un file da caricare</label>
    <input type="file" id="profile_pic" name="profile_pic"
          accept=".jpg, .jpeg, .png">
  </div>
  <div>
    <button>Invia</button>
  </div>
</form>

Questo produce un output simile a quello dell'esempio precedente:

Note: L'esempio si trova, nella versione inglese, anche su GitHub — qui puoi trovarne i sorgenti ed anche una dimostrazione di funzionamento.

Potrebbe sembrare simile, ma se si prova a selezionare un file, si vedrà che il selettore consente di scegliere solo i tipi di file specificati nell'attributo accept (il comportamento preciso differisce in base al browser ed al filesystem)

Screenshot of a macOS file picker dialog. Files other than JPEG are grayed-out and unselectable.

L'attributo accept non valida i tipi dei file selezionati; semplicemente fornisce un suggerimento per il browser per guidare l'utente alla scelta di file del tipo giusto. In molti casi è ancora possibile per l'utente abilitare o disabilitare un'opzione nel selettore di file che rende possibile sovrascrivere questa limitazione e quindi selezionare i file che vuole, scegliendone uno di un tipo non corretto.

A causa di ciò è buona norma accertarsi che l'attributo accept sia corredato da una corretta validazione lato server.

Note

  1. Non è possibile impostare il valore di un selettore di file da uno script — una operazione del genere non sortisce alcun effetto:

    const input = document.querySelector("input[type=file]");
    input.value = "foo";
    
  2. Quando un file viene selezionato usando un <input type="file">, il percorso reale del file originale non viene mostrato nell'attributo value per ovvie ragioni di sicurezza. Il nome del file invece viene mostrato, con aggiunti il percorso fittizio C:\fakepath\ in cima. 

  3. When a file is chosen using an <input type="file">, the real path to the source file is not shown in the input's value attribute for obvious security reasons. Instead, the filename is shown, with C:\fakepath\ appended to the beginning of it. Ci sono alcune ragioni storiche per questa stranezza, ma è supportata da tutti i browser moderni ed in effetti è definita nelle specifiche.

Esempi

In questo esempio mostreremo un selettore di file leggermente più sofisticato, che sfrutta le informazioni sui file disponibili nella proprietà HTMLInputElement.files, oltre a mostrare qualche trucchetto.

Note: Puoi trovare il sorgente completo della versione inglese di questo esempio si GitHub — file-example.html (click qui per provarne il comportamento dal vivo). Non ne spiegheremo il CSS, essendo il JavaScript l'obiettivo principale.

Per prima cosa osserviamo l'HTML:

<form method="post" enctype="multipart/form-data">
  <div>
    <label for="image_uploads">Seleziona le immagini da caricare (PNG, JPG)</label>
    <input type="file" id="image_uploads" name="image_uploads" accept=".jpg, .jpeg, .png" multiple>
  </div>
  <div class="preview">
    <p>Nessun file attualmente selezionato</p>
  </div>
  <div>
    <button>Invia</button>
  </div>
</form>

Questo, ancora una volta, è simile all'esempio precedente - nulla di speciale di cui aggiungere commenti.

Proseguiamo con il JavaScript.

Nelle prime righe dello script ricaviamo i riferimenti all'input stesso della form, e l'elemento <div> di classe .preview. In seguito nascondiamo l'elemento <input> — facciamo questa operazione perchè i file input di solito non hanno un bell'aspetto ed hanno uno stile piuttosto inconsistente tra un browser e l'altro. Si potrà quindi attivare l'elemento input cliccando sulla sua <label>, così che sia più comodo nascondele l'input e dare uno stile alla label simile ad un bottone, così che l'utente sappia che si tratti di un elemento interattivo ed interagisca con questo per caricare i file.

const input = document.querySelector('input');
const preview = document.querySelector('.preview');

input.style.opacity = 0;

Note: La opacity viene utilizzata per nascondere il file input al posto di visibility: hiddendisplay: none, perchè le tecnologie assistive interpretano gli ultimi due stili come un'indicazione che non si tratti di elementi interattivi.

A questo punto aggiungiamo un "event listener" all'input, che intercetti il cambio di elementi selezionati (in questo caso qundo i file vengono selezionati). L'event listener invoca la nostra funzione updateImageDisplay().

input.addEventListener('change', updateImageDisplay);

Quando viene invocata la funzione updateImageDisplay():

  • Usiamo un loop while per svuotare il <div> del contenuto precedente.
  • Prendiamo l'oggetto FileList che contiene le informazioni di tutti i file selezionati e lo salviamo in una variabile che chiamiamo curFiles.
  • Controlliamo che non sia selezionato alcun file, verificando che curFiles.length sia ugule a 0, nel qual caso stampiamo un messaggio nel <div> ad indicare che non ci sono file selezionati.
  • Se ci sono file selezionati, cicliamo su ciascuno, stampandone le informazioni nel <div> di anteprima. Da notare:
  • Usiamo la funzione validFileType() per controllare che il file sia del tipo corretto (e.g. che il tipo di immagine sia tra quelli specificati nell'attributo accept).
  • Se così fosse:
    • Stampiamo il nome e la dimensione del file in una lista nel preedente <div>. La funzione returnFileSize() restituisce una versione formattata della dimensione in bytes/KB/MB (di default il browser riporta una dimensione assoluta in bytes)
    • Generiamo una anteprima in miniatira dell'immagine chiamando URL.createObjectURL(curFiles[i]). Quindi inseriamo l'immagine anche nella lista di oggetti creando un nuovo tag <img> ed impostando la sua src con la miniatura generata.
  • Se il tipo di file non è valido mostriamo un messaggio nella lista di oggetti per indicare all'utente che deve selezionarne uno di un tipo differente.
function updateImageDisplay() {
  while(preview.firstChild) {
    preview.removeChild(preview.firstChild);
  }

  const curFiles = input.files;
  if(curFiles.length === 0) {
    const para = document.createElement('p');
    para.textContent = 'Nessun file selezionato per il caricamento';
    preview.appendChild(para);
  } else {
    const list = document.createElement('ol');
    preview.appendChild(list);

    for(const file of curFiles) {
      const listItem = document.createElement('li');
      const para = document.createElement('p');
      if(validFileType(file)) {
        para.textContent = `File ${file.name}, dimensione ${returnFileSize(file.size)}.`;
        const image = document.createElement('img');
        image.src = URL.createObjectURL(file);

        listItem.appendChild(image);
        listItem.appendChild(para);
      } else {
        para.textContent = `File ${file.name}: tipo di file non valido. Aggiorna la tua selezione.`;
        listItem.appendChild(para);
      }

      list.appendChild(listItem);
    }
  }
}

La funzione personlizzata validFileType() prende un oggetto File come parametro, quindi usa Array.prototype.includes() per verificare che ci sia almeno una corrispondenza con la proprietà type del file. Se viene trovata una corrispodenza la funzione restituisce il valore true, altrimenti false.

// https://developer.mozilla.org/it/docs/Web/Media/Formats/Image_types
const fileTypes = [
  "image/apng",
  "image/bmp",
  "image/gif",
  "image/jpeg",
  "image/pjpeg",
  "image/png",
  "image/svg+xml",
  "image/tiff",
  "image/webp",
  "image/x-icon"
];

function validFileType(file) {
  return fileTypes.includes(file.type);
}

La funzione returnFileSize() prende un numero (di byte, preso dalla proprietà size), e lo trasforma in una stringa correttamente formattata in bytes/KB/MB.

function returnFileSize(number) {
  if(number < 1024) {
    return number + 'bytes';
  } else if(number >= 1024 && number < 1048576) {
    return (number/1024).toFixed(1) + 'KB';
  } else if(number >= 1048576) {
    return (number/1048576).toFixed(1) + 'MB';
  }
}

L'esempio è simile al seguente, proviamo:

Specifiche

Specifica Stato Commento
HTML Living Standard
The definition of '<input type="file">' in that specification.
Living Standard Definzione iniziale
HTML 5.1
The definition of '<input type="file">' in that specification.
Recommendation Definizione iniziale
HTML Media Capture
The definition of 'capture attribute' in that specification.
Recommendation Attributo capture iniziale

Compatibilità browser

Update compatibility data on GitHub
DesktopMobile
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung Internet
type="file"Chrome Full support 1Edge Full support 12Firefox Full support 1
Notes
Full support 1
Notes
Notes You can set as well as get the value of HTMLInputElement.files in all modern browsers; this was most recently added to Firefox, in version 57 (see bug 1384030).
IE Full support YesOpera Full support 11Safari Full support 1WebView Android Full support YesChrome Android Full support YesFirefox Android Full support 4Opera Android Full support 11Safari iOS Full support YesSamsung Internet Android Full support Yes

Legend

Full support  
Full support
See implementation notes.
See implementation notes.

Vedi anche