Caricamento di file con AJAX

Non riesco a raggiungere la fine delle cose divertenti che puoi fare con le tecnologie web emergenti. Oggi ti mostrerò come fare qualcosa che, fino all'ultimo, è stato quasi senza precedenti: caricare file via AJAX.

Oh, certo, ci sono stati hack; ma se sei come me, e ti senti sporco ogni volta che digiti iframe, ti piacerà molto Unisciti a me dopo il salto!

Alla ricerca di una soluzione rapida?

Se stai cercando una soluzione rapida, c'è una grande raccolta di script per il caricamento di file e applicazioni su Envato Market.я

Questo upload di file HTML5 è particolarmente elegante: puoi aggiungere facilmente i file trascinandoli e rilasciandoli o facendo clic. Tutti i file verranno caricati tramite AJAX o possono essere aggiunti all'interno di un modulo e i file possono essere rinominati prima del caricamento. Un'ottima soluzione rapida se è quello che stai cercando!


Perché non ci facciamo passare le brutte notizie??

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

Il nostro caricamento AJAX funzionerà fino a quando formdata è disponibile; in caso contrario, l'utente riceverà un caricamento normale.

Ci sono tre componenti principali del nostro progetto.

  • Il multiplo attributo sul file ingresso elemento.
  • Il FileReader oggetto dalla nuova API File.
  • Il formdata oggetto da XMLHttpRequest2.

Noi usiamo il multiplo attributo per consentire all'utente di selezionare più file da caricare (il caricamento di più file funziona normalmente anche se formdata non è disponibile). Come vedrai, FileReader ci consente di mostrare le miniature degli utenti dei file che stanno caricando (ci aspettiamo immagini).

Nessuna delle nostre tre funzioni funziona in IE9, quindi tutti gli utenti di IE avranno un'esperienza di caricamento normale (anche se capisco che il supporto per 'FileReader' è disponibile in IE10 Dev Preview 2). FileReader non funziona nell'ultima versione di Safari (5.1), quindi non otterranno le miniature, ma riceveranno il caricamento AJAX e il messaggio di conferma. Finalmente, Opera 10.50 ha FileReader supporto ma non formdata supporto, quindi riceveranno miniature, ma caricamenti normali.

Con quello fuori mano, prendiamo la codifica!


Passaggio 1: markup e styling

Iniziamo con alcuni markup e stili di base. Naturalmente, questa non è la parte principale di questo tutorial, non ti tratterò come un principiante.

L'HTML

    API file HTML5    

Carica le tue immagini

Piuttosto semplice, eh? Abbiamo un modulo su cui scrivere upload.php, che vedremo in un secondo, e un singolo elemento di input, di tipo file. Si noti che ha il valore booleano multiplo attributo, che consente all'utente di selezionare più file contemporaneamente.

Questo è tutto ciò che c'è da vedere qui. Andiamo avanti.

Il CSS

body font: 14px / 1.5 helvetica-neue, helvetica, arial, san-serif; padding: 10px;  h1 margin-top: 0;  #main width: 300px; margin: auto; sfondo: #ececec; imbottitura: 20px; border: 1px solid #ccc;  # image-list list-style: none; margin: 0; padding: 0;  # image-list li background: #fff; border: 1px solid #ccc; text-align: center; padding: 20px; margin-bottom: 19px;  # image-list li img width: 258px; allineamento verticale: medio; border: 1px solid # 474747; 

Assolutamente no shockers qui.


Passaggio 2: il PHP

Dobbiamo essere in grado di gestire anche i caricamenti di file sul back-end, quindi copriamolo dopo.

upload.php

 $ error) if ($ error == UPLOAD_ERR_OK) $ name = $ _FILES ["images"] ["name"] [$ key]; move_uploaded_file ($ _FILES ["images"] ["tmp_name"] [$ key], "uploads". $ _FILES ['images'] ['name'] [$ key]);   eco "

Immagini caricate con successo

";

Tieni presente che queste sono state le prime righe di PHP che avevo scritto facilmente in un anno (sono un ragazzo Ruby). Probabilmente dovresti fare un po 'di più per la sicurezza; tuttavia, ci stiamo semplicemente assicurando che non ci siano errori di caricamento. Se questo è il caso, usiamo il built-in move_uploaded_file per spostarlo in un uploads cartella. Non dimenticare di accertarti che la cartella sia scrivibile.

Quindi, al momento, dovremmo avere un modulo di caricamento funzionante. Scegli un'immagine (più, se vuoi e il tuo browser ti consente), fai clic su ?Caricare files!? pulsante e ottieni il messaggio ?Immagini caricate con successo.?

Ecco come appare il nostro mini-progetto:

Ma, andiamo, è il 2011: vogliamo di più. Noterai che abbiamo collegato jQuery e un upload.js file. Facciamo un crack così aperto ora.


Passaggio 3: JavaScript

Non perdiamo tempo: eccoci qui!

(function () var input = document.getElementById ("images"), formdata = false; if (window.FormData) formdata = new FormData (); document.getElementById ("btn"). style.display = "none "; ();

Ecco cosa iniziamo con. Creiamo due variabili: ingresso è il nostro elemento di input di file; formdata verrà utilizzato per inviare le immagini al server se il browser lo supporta. Inizializziamo a falso e quindi controlla se il browser supporta formdata; Se lo fa, creiamo un nuovo formdata oggetto. Inoltre, se possiamo inviare le immagini con AJAX, non abbiamo bisogno del? Carica immagini !? pulsante, in modo che possiamo nasconderlo. Perché non ne abbiamo bisogno? Bene, stiamo caricando automaticamente le immagini immediatamente dopo che l'utente le ha selezionate.

Il resto del JavaScript andrà nella tua funzione anonima di auto-invocazione. Successivamente creiamo una piccola funzione di supporto che mostrerà le immagini una volta che il browser le ha:

function showUploadedItem (source) var list = document.getElementById ("image-list"), li = document.createElement ("li"), img = document.createElement ("img"); img.src = source; li.appendChild (img); list.appendChild (li); 

La funzione accetta un parametro: la sorgente dell'immagine (vedremo come la otterremo presto). Quindi, troviamo semplicemente l'elenco nel nostro markup e creiamo un elemento di elenco e un'immagine. Impostiamo la sorgente dell'immagine sulla fonte che abbiamo ricevuto, inseriamo l'immagine nella voce dell'elenco e inseriamo l'elemento della lista nella lista. Ecco!

Successivamente, dobbiamo effettivamente prendere le immagini, visualizzarle e caricarle. Come abbiamo detto, lo faremo quando il onchange l'evento è attivato sull'elemento di input.

if (input.addEventListener) input.addEventListener ("change", function (evt) var i = 0, len = this.files.length, img, reader, file; document.getElementById ("response"). innerHTML = "Caricamento?" Per (; i < len; i++ )  file = this.files[i]; if (!!file.type.match(/image.*/))    , false); 

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

C'è di più, ma iniziamo con questo. Prima di tutto, non dobbiamo preoccuparci del modello di eventi proprietario di IE, perché IE9 + supporta lo standard addEventListener funzione (e IE9 e down non supportano le nostre nuove funzionalità).

Quindi, cosa vogliamo fare quando l'utente ha selezionato i file? Innanzitutto, creiamo alcune variabili. L'unico importante adesso è len = this.files.length. I file che l'utente ha selezionato saranno accessibili dall'oggetto this.files. Al momento, ci occupiamo solo di lunghezza proprietà, quindi possiamo eseguire il loop dei file?

? che è esattamente quello che faremo dopo. All'interno del nostro ciclo, impostiamo il file corrente su file per facilità di accesso. La prossima cosa che facciamo è confermare che il file è un'immagine. Possiamo farlo confrontando il genere proprietà con un'espressione regolare. Stiamo cercando un tipo che inizia con? Image? ed è seguito da qualsiasi cosa. (Il doppio botto in avanti converte il risultato in un booleano.)

Quindi, cosa facciamo se abbiamo un'immagine nelle nostre mani?

if (window.FileReader) reader = new FileReader (); reader.onloadend = function (e) showUploadedItem (e.target.result); ; reader.readAsDataURL (file);  if (formdata) formdata.append ("images []", file); 

Controlliamo per vedere se il browser supporta la creazione FileReader oggetti. Se lo fa, ne creeremo uno.

Ecco come usiamo a FileReader oggetto: stiamo per passare il nostro file oggetto al reader.readAsDataURL metodo. Questo crea un URL di dati per l'immagine caricata. Tuttavia, non funziona nel modo che ci si potrebbe aspettare. L'URL dei dati non viene restituito dalla funzione. Invece, l'url di dati farà parte di un oggetto evento.

Con questo in mente, dovremo registrare una funzione su reader.onloadend evento. Questa funzione accetta un oggetto evento, con il quale otteniamo l'url dei dati: è a e.target.result (sì, e.target è il lettore oggetto, ma ho avuto problemi durante l'utilizzo lettore al posto di e.target all'interno di questa funzione). Passeremo questa url di dati al nostro showUploadedItem funzione (che abbiamo scritto sopra).

Successivamente, controlliamo per il formdata oggetto. Ricorda, se il browser supporta formdata, formdata sarà un formdata oggetto; altrimenti, lo sarà falso. Quindi, se abbiamo un formdata oggetto, chiameremo il aggiungere metodo. Lo scopo di a formdata l'oggetto è per contenere i valori che stai inviando tramite un modulo; così la aggiungere il metodo prende semplicemente una chiave e un valore. Nel nostro caso, la nostra chiave è immagini[]; aggiungendo le parentesi quadre alla fine, ci assicuriamo ogni volta che lo facciamo aggiungere un altro valore, in realtà lo stiamo aggiungendo a quell'array, invece di sovrascrivere il Immagine proprietà.

Abbiamo quasi finito. Nel nostro ciclo for, abbiamo mostrato ognuna delle immagini per l'utente e le abbiamo aggiunte al formdata oggetto. Ora, abbiamo solo bisogno di caricare le immagini. Fuori da per loop, ecco l'ultimo pezzo del nostro puzzle:

if (formdata) $ .ajax (url: "upload.php", tipo: "POST", dati: formdata, processData: false, contentType: false, success: function (res) document.getElementById ("response") ) .innerHTML = res;); 

Ancora una volta, dobbiamo assicurarci di averlo formdata supporto; se non lo facciamo, il? Upload Files !? il pulsante sarà visibile ed è così che l'utente caricherà le foto. Tuttavia, se abbiamo formdata supporto, ci occuperemo del caricamento tramite AJAX. Stiamo usando jQuery per gestire tutte le stranezze di AJAX attraverso i browser.

Probabilmente hai familiarità con jQuery $ .ajax metodo: lo passi un oggetto opzioni. Il url, genere, e successo le proprietà dovrebbero essere ovvie. Il dati la proprietà è nostra formdata oggetto. Notare quelli dati di processo e tipo di contenuto proprietà. Secondo la documentazione di jQuery, dati di processo è vero per impostazione predefinita, e elaborerà e trasformerà i dati in una stringa di query. Non vogliamo farlo, quindi lo impostiamo falso. Stiamo anche ambientando tipo di contenuto a falso per assicurarsi che i dati arrivino al server come ci aspettiamo.

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

E dopo aver selezionato le immagini, vedranno questo:

E le immagini sono state caricate:


È un involucro!

Il caricamento di file tramite AJAX è piuttosto interessante ed è fantastico che queste nuove tecnologie supportino questo senza la necessità di lunghi hack. Se hai qualche domanda su ciò che abbiamo fatto qui, colpisci quei commenti! Grazie mille per la lettura!

E se hai ancora bisogno di aiuto con questo o altri problemi di codifica, trova supporto su Envato Studio.

Scopri JavaScript: la guida completa

Abbiamo creato una guida completa per aiutarti a imparare JavaScript, sia che tu stia appena iniziando come sviluppatore web o che desideri esplorare argomenti più avanzati.