Advertisement
  1. Web Design
  2. HTML/CSS
  3. HTML

Caricamento dei file con AJAX

Scroll to top
Read Time: 9 min

() translation by (you can also view the original English article)

Non riesco a raggiungere la fine del divertimento con le cose che puoi fare con le tecnologie web emergenti. Oggi, ho intenzione di mostrarvi come fare qualcosa che — fino a poco fa — è stato quasi senza precedenti: caricamento dei file tramite AJAX.

Oh, certo, ci sono stati degli hack; ma se siete come me e vi sentite sporchi ogni volta che digitate iframe, vi piacerà un sacco. Unitevi a me dopo il salto!

Alla ricerca di una soluzione rapida?

Se state cercando una soluzione rapida, c'è una grande collezione di script di upload di file e applicazioni sul mercato di Envato.

Questo uploader di file in HTML5 è particolarmente chiaro — è possibile aggiungere facilmente i file trascinandoli e rilasciandoli o cliccandoci sopra. Tutti i file verranno caricati tramite AJAX o possono essere aggiunti all'interno di un modulo, e possono essere rinominati prima di caricarli. Una soluzione ottima, veloce se questo è quello che stai cercando!


Perché non ci sono brutte notizie?

Questo non funziona in tutti i browser. Tuttavia, con qualche miglioramento progressivo (o qualunque sia la parola d'ordine attuale), avremo una pagina di caricamento che funzionerà su IE6 (anche se senza i bit AJAXy).

Il nostro caricamento AJAX funzionerà finché FormData sarò disponibile; in caso contrario, l'utente otterrà un caricamento normale.

Ci sono tre componenti principali per il nostro progetto.

  • L'attributo multiple sull'elemento di input file.
  • L'oggetto FileReader dalla nuova File API.
  • L'oggetto FormData da XMLHttpRequest2.

Usiamo l'attributo multiple per consentire all'utente di selezionare più file per il caricamento (l'upload multiplo di file funzionerà normalmente anche se FormData non è disponibile). Come si vedrà, FileReader permette di mostrare all'utente le miniature dei file che si stanno caricando (ci aspettiamo che siano immagini).

Nessuno delle nostre tre caratteristiche funziona in IE9, quindi tutti gli utenti di IE avranno un'esperienza di caricamento normale (anche se il supporto per 'FileReader' è disponibile in IE10 Dev Preview 2). FileReader non funziona nell'ultima versione di Safari (5.1), quindi non si avranno le miniature, ma si avrà il caricamento AJAX e il messaggio di conferma. Infine, Opera 10.50 ha supporto FileReader ma non supporta FormData, quindi otterremo le miniature, ma con caricamento normale.

Dopo tutto questo, vediamo il codice!


Passaggio 1: Il Markup e lo stile

Cominciamo con il markup di base e lo styling. Naturalmente, questa non è la parte principale di questo tutorial, non voglio trattarti come un novizio.

Il codice HTML

1
<!DOCTYPE html>
2
<html lang="en">
3
<head>
4
  <meta charset="UTF-8" />
5
  <title>HTML5 File API</title>
6
  <link rel="stylesheet" href="style.css" />
7
</head>
8
<body>
9
  <div id="main">
10
    <h1>Upload Your Images</h1>
11
    <form method="post" enctype="multipart/form-data"  action="upload.php">
12
      <input type="file" name="images" id="images" multiple />
13
      <button type="submit" id="btn">Upload Files!</button>
14
    </form>
15
16
    <div id="response"></div>
17
    <ul id="image-list">
18
19
    </ul>
20
  </div>
21
22
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
23
  <script src="upload.js"></script>
24
</body>
25
</html>

Abbastanza essenziale, eh? Abbiamo un modulo che inviamo a upload.php, che vedremo in un secondo e un singolo elemento di input, di tipo file. Si noti che ha il valore l'attributo booleano multiple, che consente all'utente di selezionare più file contemporaneamente.

Questo è davvero tutto quello che c'è da vedere qui. Andiamo avanti.

Il CSS

1
body {
2
  font: 14px/1.5 helvetica-neue, helvetica, arial, san-serif;
3
  padding:10px;
4
}
5
6
h1 {
7
  margin-top:0;
8
}
9
10
#main {
11
  width: 300px;
12
  margin:auto;
13
  background: #ececec;
14
  padding: 20px;
15
  border: 1px solid #ccc;
16
}
17
18
#image-list {
19
  list-style:none;
20
  margin:0;
21
  padding:0;
22
}
23
#image-list li {
24
  background: #fff;
25
  border: 1px solid #ccc;
26
  text-align:center;
27
  padding:20px;
28
  margin-bottom:19px;
29
}
30
#image-list li img {
31
  width: 258px;
32
  vertical-align: middle;
33
  border:1px solid #474747;
34
}

Assolutamente nessun shock qui.


Passaggio 2: Il PHP

Dobbiamo essere in grado di gestire l'upload di file sul back-end pure, quindi scopriamo come.

upload.php

1
<?php
2
3
foreach ($_FILES["images"]["error"] as $key => $error) {
4
  if ($error == UPLOAD_ERR_OK) {
5
    $name = $_FILES["images"]["name"][$key];
6
    move_uploaded_file( $_FILES["images"]["tmp_name"][$key], "uploads/" . $_FILES['images']['name'][$key]);
7
  }
8
}
9
10
echo "<h2>Successfully Uploaded Images</h2>";

Tenete a mente che queste sono state le prime righe di PHP scritte in un anno (io sviluppo in Ruby). Probabilmente si dovrebbe fare un po' di più per la sicurezza; tuttavia, stiamo semplicemente controllando che non siano presenti errori di caricamento. Se questo è il caso, usiamo la funzione incorporata move_uploaded_file per spostarlo in una cartella di uploads. Non dimenticate di verificare che la cartella abbia permessi di scrittura.

Così, adesso, dovremmo avere un modulo di caricamento funzionante. Scegli un'immagine (multiple, se lo si desidera e il vostro browser lo consente), fare clic sul pulsante "Carica file!", e verrà visualizzato il messaggio "immagini caricate correttamente."

Ecco come appare il nostro mini-progetto finora:

The styled formThe styled formThe styled form

Ma, andiamo, è il 2011: vogliamo di più. Noterete che abbiamo collegato jQuery e un file di upload.js. Usiamoli ora.


Passaggio 3: Il JavaScript

Non perdiamo tempo: andiamo!

1
(function () {
2
  var input = document.getElementById("images"),
3
      formdata = false;
4
    
5
  if (window.FormData) {
6
    formdata = new FormData();
7
    document.getElementById("btn").style.display = "none";
8
  }
9
  
10
11
}();

Ecco con cosa iniziamo. Creiamo due variabili: l'input è il nostro elemento di input file; FormData sarà utilizzato per inviare le immagini al server, se il browser lo supporta. Inizializziamola su false e quindi verifichiamo se il browser supporta FormData; in caso affermativo, creiamo un nuovo oggetto FormData. Inoltre, se possiamo inviare le immagini con AJAX, non abbiamo bisognodel pulsante "Carica immagini!", quindi possiamo nasconderlo. Perché non ne abbiamo bisogno? Beh, stiamo andando a caricare in modo auto-magico le immagini immediatamente dopo che l'utente le seleziona.

Il resto del JavaScript andrà nella vostra funzione anonima autoinvocante. Creiamo quindi una piccola funzione di supporto che mostrerà le immagini una volta che il browser le vede:

1
function showUploadedItem (source) {
2
  var list = document.getElementById("image-list"),
3
      li   = document.createElement("li"),
4
      img  = document.createElement("img");
5
    img.src = source;
6
    li.appendChild(img);
7
  list.appendChild(li);
8
}

La funzione accetta un parametro: l'origine dell'immagine (vedremo come ottennerla presto). Quindi, dobbiamo semplicemente trovare l'elenco nel nostro markup e creare una voce di elenco e un'immagine. Impostiamo l'origine dell'immagine sull'origine che abbiamo ricevuto, inseriamo l'immagine nella voce dell'elenco e mettiamo l'elemento nell'elenco. Voilà!

Poi, dobbiamo prendere le immagini, visualizzarle e caricarle. Come abbiamo detto, lo faremo quando viene generato l'evento onchange sull'elemento di input.

1
if (input.addEventListener) {
2
  input.addEventListener("change", function (evt) {
3
    var i = 0, len = this.files.length, img, reader, file;
4
    
5
    document.getElementById("response").innerHTML = "Uploading . . ."
6
    
7
    for ( ; i < len; i++ ) {
8
      file = this.files[i];
9
  
10
      if (!!file.type.match(/image.*/)) {
11
12
      } 
13
    }
14
      
15
  }, false);
16
}

Non dobbiamo preoccuparci del modello di eventi proprietario di IE, perché IE9+ supporta la funzione addEventListener standard.

C'è di più, ma cominciamo con questo. In primo luogo, non dobbiamo preoccuparci del modello di eventi proprietario di IE, perché IE9 + supporta la funzione standard addEventListener (e IE9 e versioni minori non supportano le nuove funzionalità).

Allora, cosa vogliamo fare quando l'utente ha selezionato il file? In primo luogo, creiamo alcune variabili. La sola importante ora è len = this.files.length. I files che l'utente ha selezionato saranno accessibili dall'oggetto this.files. Al momento, siamo solo interessati alla proprietà length, così noi possiamo fare un ciclo sui files...

... che è esattamente quello che stiamo faremo dopo. All'interno del nostro ciclo, abbiamo impostato il file corrente su file per facilità di accesso. La prossima cosa che facciamo è confermare che il file è un'immagine. Possiamo farlo confrontando la proprietà type con un'espressione regolare. Stiamo cercando un tipo che inizia con "image" ed è seguito da qualunque stringa. (Il doppio punto esclamativo all'inizio converte il risultato in un valore booleano).

Allora, cosa facciamo se abbiamo un'immagine?

1
if ( window.FileReader ) {
2
  reader = new FileReader();
3
  reader.onloadend = function (e) { 
4
    showUploadedItem(e.target.result);
5
  };
6
  reader.readAsDataURL(file);
7
}
8
if (formdata) {
9
  formdata.append("images[]", file);
10
}

Controlliamo per vedere se il browser supporta la creazione di oggetti FileReader. In caso positivo, ne creeremo uno.

Ecco come usiamo un oggetto FileReader: stiamo andando a passare il nostro oggetto file al metodo reader.readAsDataURL. Questo crea un data-url per l'immagine caricata. Non funziona nel modo che uno si potrebbe aspettare, però. Il data url non è passato indietro dalla funzione. Invece, lil data url sarà parte di un evento.

Con questo in mente, abbiamo bisogno di registrare una funzione sull'evento reader.onloadend. Questa funzione accetta un evento, da cui otteniamo il data url: è su e.target.result (Sì, e.target è l'oggetto del reader, ma ho avuto problemi quando ho utilizzato il reader al posto di e.target all'interno di questa funzione). Dobbiamo solo passare questo data url alla nostra funzione showUploadedItem (che abbiamo scritto in precedenza).

Poi, controlliamo l'oggetto formdata. Ricordate, se il browser supporta FormData, formdata sarà un oggetto FormData; in caso contrario, sarà false. Quindi, se abbiamo un oggetto FormData, chiameremo il metodo append. Lo scopo di un oggetto FormData è contenere i valori che si inviano tramite un modulo; così, il metodo append prende semplicemente una chiave e un valore. Nel nostro caso, la nostra chiave è images[]; aggiungendo le parentesi quadre alla fine, ci assicuriamo che ogni volta che aggiungiamo (append) un altro valore, lo stiamo accodando a tale array, anziché sovrascrivere la proprietà image.

Abbiamo quasi finito. Nel nostro ciclo for, abbiamo visualizzato ciascuna delle immagini per l'utente e le abbiamo aggiunte all'oggetto formdata. Ora, abbiamo solo bisogno di caricare le immagini. All'esterno del ciclo for, ecco l'ultimo pezzo del nostro puzzle:

1
if (formdata) {
2
  $.ajax({
3
    url: "upload.php",
4
    type: "POST",
5
    data: formdata,
6
    processData: false,
7
    contentType: false,
8
    success: function (res) {
9
      document.getElementById("response").innerHTML = res; 
10
    }
11
  });
12
}

Ancora una volta, dobbiamo assicurarci di avere supporto a FormData; se non lo facciamo, il pulsante "Upload file!" sarà visibile, ed è così che l'utente caricherà le foto. Tuttavia, se abbiamo supporto di FormData, ci occuperemo di caricarlo tramite AJAX. Stiamo usando jQuery per gestire tutte le stranezze di AJAX tra i vari browser.

Hai probabilmente familiarità con il metodo $.ajax di jQuery: gli si passa un oggetto di opzioni. La proprietà url, type e success dovrebbero esserere ovvie. La proprietà data è il nostro oggetto formdata. Notate le proprietà processData e contentType. Secondo la documentazione di jQuery, processData è true per impostazione predefinita ed elaborerà e trasformerà i dati in una stringa di query. Non vogliamo farlo, per questo abbiamo impostato su false. Inoltre stiamo regolando contentType su false per assicurarci che i dati che inviamo al server arrivino come ci aspettiamo che facciano.

E questo è tutto. Ora, quando l'utente carica la pagina,  vede questo:

Tutorial ImageTutorial ImageTutorial Image

E dopo che ha selezionato le immagini, vedrà questo:

Tutorial ImageTutorial ImageTutorial Image

E le immagini sono state caricate:

Tutorial Image

Questo è tutto!

Caricare dei file tramite AJAX è piuttosto facile, ed è bello che queste nuove tecnologie lo supportano senza la necessità di hack. Se hai dei dubbi su quello che abbiamo fatto qui, scrivilo nei commenti! Grazie mille per la lettura!

E se hai ancora bisogno di aiuto con questo o qualsiasi altro problema di codifica, è possibile trovare supporto su Envato Studio.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.