Carica l'immagine trascinandola. HTML5: caricamento di file tramite trascinamento della selezione. Lavorare con i file scaricati

Grazie a tutti! In questo articolo voglio parlare di alcuni dei miei esperimenti con HTML5. Inizierò da lontano. Tutti noi dobbiamo periodicamente lavorare con diverse interfacce web e spesso abbiamo la sensazione che questo lavoro potrebbe essere organizzato in modo più efficiente.

Forse in alcuni casi la colpa è degli sviluppatori del servizio, ma spesso il problema risiede nelle limitazioni imposte dai browser. Consideriamo il caricamento dei file sul server. Nella maggior parte dei casi, ti verrà presentato un campo standard con un pulsante per selezionare un file dal tuo computer e/o un campo in cui puoi specificare l'URL di un file che si trova da qualche parte sul Web.

Per ora non toccheremo il download di file da un computer locale, ho intenzione di pubblicare un post separato su questo argomento, diamo un'occhiata al download da un server remoto.

I problemi iniziano fin dal primo passo. Anche se sai chiaramente dove cercare un URL e sei bravo a usare strumenti come Firebug, ci vorranno comunque alcuni clic per ottenere l'indirizzo giusto. Sarebbe molto più comodo trascinare semplicemente l'immagine desiderata da una finestra del browser all'altra.

Mostrerò un esempio dell'implementazione di tale interfaccia in questo articolo. Se vuoi, puoi vedere come funziona nella pagina demo o .

Nota! Questo esempio Funziona solo nel browser Google Chrome. In teoria, Firefox e Safari supportano tutte le tecnologie necessarie, ma non le ho ancora capite. Principalmente ho preso immagini da Wikipedia come oggetti da trascinare. Sono stati notati diversi problemi legati ai caratteri non latini nelle URL delle immagini, ma per non sovraccaricare l'esempio di controlli e trasformazioni li ho lasciati così come sono.

Principio di funzionamento

Lo standard HTML5 fornisce il supporto per il trascinamento e il rilascio degli oggetti della pagina. A proposito, ho già mostrato un esempio dell'implementazione più semplice di D&D: Drag & Drop utilizzando HTML5. Inoltre, ci sono parecchie librerie JavaScript che implementano il supporto D&D.

Ma qui è importante capire che se devi "trascinare" immagini da risorse di terze parti, non sarai in grado di utilizzare le librerie. Perché non sarai in grado di aggiungere il tuo codice JS alla pagina di qualcun altro. E per scaricare un'immagine, dobbiamo ottenere il suo URL, ad es. Insieme all'oggetto trascinato il browser deve trasmettere anche i propri parametri (ad esempio l'attributo src di un'immagine o l'intero tag img).

In questo caso, possiamo creare un “ricevitore” di immagini sulla nostra pagina. Questo sarà un div normale con un gestore di eventi drop assegnato. Se l'utente “rilascia” l'immagine sopra questo div, verrà chiamato il gestore e nel primo parametro riceverà un oggetto contenente informazioni sull'immagine trascinata.

Implementazione

Cominciamo con la nostra pagina di applicazione.

Caricamento immagini


Contiene due blocchi: immagini – qui mostreremo le immagini scaricate e img_target – devi trascinare le immagini su questo blocco. Nella parte inferiore della pagina colleghiamo la libreria jQuery e lo script main.js, che invierà informazioni sulle immagini trascinate al server.

Diamo un'occhiata a main.js
$(funzione() (
$("#img_target")
.bind("dragenter", funzione(evento) (
$(this).addClass("drop_here");
restituire falso;
})
.bind("dragleave", funzione(evento) (

restituire falso;
})
.bind("dragover", funzione(evento) (
restituire falso;
})
.bind("rilascia", funzione(evento) (
$(this).removeClass("drop_here");
var srcRegex = /src=\"([^\s]+)\"/ig;
var data = event.originalEvent.dataTransfer.getData("text/html");
var img_data = srcRegex.exec(dati);
$.post("upload.php", ("file_url":img_data), funzione(res) (
var risposta = eval("(" + res + ")");
$("#immagini").append($(""));
});
restituisce vero;
});
});
Qui assegniamo i gestori agli eventi dragenter, dragleave e dragover. Tutti dovrebbero semplicemente restituire false e, per informare in qualche modo l'utente che l'immagine può essere “rilasciata”, nel gestore dragenter impostiamo la classe CSS drop_here per il blocco ricevitore. La maggior parte del lavoro viene svolto nel gestore dell'evento drop. Quando si verifica questo evento, leggiamo le informazioni sull'oggetto "reset" e "tagliamo" il valore dell'attributo src, ad es. URL dell'immagine. Le informazioni vengono trasferite nell'oggetto event.originalEvent.dataTransfer.

Quindi formiamo una normale richiesta AJAX e passiamo l'URL trovato come parametro. Lo script del server (upload.php) riceverà l'URL dell'immagine sul server remoto e lo caricherà. E in risposta alla richiesta AJAX, invierà il nuovo URL dell'immagine caricata. A sua volta, il gestore della richiesta AJAX creerà un tag img e lo inserirà nel blocco immagini. Pertanto, le immagini scaricate appariranno sopra il campo di download.

Considera upload.php

Il principio di funzionamento è il seguente. Leggiamo l'URL dell'immagine e proviamo a scaricarla. Se l'immagine è stata caricata, salvala nella cartella di caricamento. La ricezione di un'immagine da un server remoto viene effettuata utilizzando le funzioni fread. Il file viene letto in blocchi da 1kB. Questo approccio consente di interrompere il download di un file se la sua dimensione supera un limite specificato (in in questo caso 300kB).

Dopo aver scaricato il file, generiamo un URL per esso e lo inviamo al browser in formato JSON. Come puoi vedere, implementare un bootloader di questo tipo non è difficile. Ed è abbastanza comodo da usare. Naturalmente lo svantaggio principale è il supporto di HTML5 da parte dei browser, o meglio la sua mancanza, ma se state creando un'interfaccia per i dipendenti di un'azienda e potete specificare il tipo di browser, allora è possibile utilizzare HTML5.

Continuiamo a creare il nostro download drag and drop e oggi scriveremo il nostro server e inizieremo a scrivere il codice JavaScript.

Nell'ultimo articolo abbiamo scritto un file index.html e gli stili per esso. Oggi scriveremo un server che scaricherà i file e invierà le informazioni su di essi allo script, ma prima parliamo della struttura dei file che avremo:

  • .htaccess
  • indice.html
  • style.css
  • caricare.php
  • caricamenti

Tutto è chiaro con i file index.html e style.css. Impostiamo semplicemente la codifica nel file .htaccess in modo che non ci siano problemi.

Aggiungi set di caratteri predefinito UTF-8

Il file upload.php caricherà i file sul server nella cartella uploads.

Allora cominciamo con php. Per fare ciò, apri il file upload.php e scrivi quanto segue:

All'inizio del file scriviamo un'intestazione Content-Type per dire al browser che riceverà json. Quindi creiamo un array $uploaded vuoto e controlliamo se sono presenti file. Se sì, li esaminiamo e li carichiamo nella nostra directory di caricamento, inoltre riempiamo il nostro array principale $uploaded con sottoarray che conterranno informazioni sui file. Nel nostro caso, questo è il nome del file e la sua posizione. Infine, convertiamo il nostro array in json e lo produciamo. Come puoi vedere, il server non è affatto complicato.

Passiamo ora al file index.html


Trascina i file qui

(funzione() (
var dropzone = document.getElementById("dropzone");
dropzone.ondragover = funzione() (
this.className = "dropzone dragover";
this.innerHTML = "Rilascia il mouse";
restituire falso;
};

Dropzone.ondragleave = funzione() (


restituire falso;
};

Dropzone.ondrop = funzione(e) (
this.className = "dropzone";
this.innerHTML = "Trascina i file qui";
e.preventDefault();
};
})();

Ricordi la classe .dragover che abbiamo scritto nell'ultimo articolo e ho detto che sarebbe stata utilizzata quando ci fosse qualche file sopra il nostro blocco? Questo è, in effetti, ciò che abbiamo fatto ora. Quando un file appare sopra il blocco, viene attivato l'evento ondragover, in cui aggiungiamo semplicemente la nostra classe .dragover e modifichiamo il testo in "Rilascia il mouse". Quando spostiamo il mouse con il file lontano dal nostro blocco, viene attivato l'evento ondragleave, dove riportiamo tutto nella sua posizione originale. Quando una persona “rilascia” un file nel nostro blocco, viene attivato l’evento ondrop. Lì cambiamo tutto di nuovo, come all'inizio, altrimenti la classe .dragover si bloccherà e annulleremo il comportamento predefinito. Se non lo facciamo, il nostro file si aprirà semplicemente nel browser, il che non è ciò che vogliamo.

Forse in alcuni casi la colpa è degli sviluppatori del servizio, ma spesso il problema risiede nelle limitazioni imposte dai browser. Consideriamo il caricamento dei file sul server.

Nella maggior parte dei casi, ti verrà presentato un campo standard con un pulsante per selezionare un file dal tuo computer e/o un campo in cui puoi specificare l'URL di un file che si trova da qualche parte sul Web.

Per ora non toccheremo il download di file da un computer locale, ho intenzione di pubblicare un post separato su questo argomento, diamo un'occhiata al download da un server remoto.

I problemi iniziano fin dal primo passo. Anche se sai chiaramente dove cercare un URL e sei bravo a usare strumenti come Firebug, ci vorranno comunque alcuni clic per ottenere l'indirizzo giusto. Sarebbe molto più comodo trascinare semplicemente l'immagine desiderata da una finestra del browser all'altra.

Mostrerò le implementazioni di tale interfaccia in questo articolo. Se vuoi puoi vedere come funziona nella pagina demo o scaricare l'archivio con i sorgenti.

Nota! Questo esempio funziona solo nel browser Google Chrome. In teoria, Firefox e Safari supportano tutte le tecnologie necessarie, ma non le ho ancora capite.

Come oggetti da trascinare, ho preso principalmente immagini da Wikipedia. Sono stati notati diversi problemi legati ai caratteri non latini nelle URL delle immagini, ma per non sovraccaricare l'esempio di controlli e trasformazioni li ho lasciati così come sono.


Principio di funzionamento

Lo standard HTML5 fornisce il supporto per il trascinamento e il rilascio degli oggetti della pagina. A proposito, ho già mostrato un esempio dell'implementazione più semplice di D&D: Drag & Drop utilizzando HTML5. Inoltre, ci sono parecchie librerie JavaScript che implementano il supporto D&D.

Ma qui è importante capire che se devi "trascinare" immagini da risorse di terze parti, non sarai in grado di utilizzare le librerie. Perché non sarai in grado di aggiungere il tuo codice JS alla pagina di qualcun altro. E per scaricare un'immagine, dobbiamo ottenere il suo URL, ad es. Insieme all'oggetto trascinato il browser deve trasmettere anche i propri parametri (ad esempio l'attributo src di un'immagine o l'intero tag img).

In questo caso, possiamo creare un “ricevitore” di immagini sulla nostra pagina. Questo sarà un div normale con un gestore di eventi drop assegnato. Se l'utente “rilascia” l'immagine sopra questo div, verrà chiamato il gestore e nel primo parametro riceverà un oggetto contenente informazioni sull'immagine trascinata.

Implementazione

Cominciamo con la nostra pagina di applicazione.





Caricamento immagini








Contiene due blocchi: immagini - qui mostreremo le immagini caricate e img_target - devi trascinare le immagini su questo blocco.

Nella parte inferiore della pagina colleghiamo la libreria jQuery e lo script main.js, che invierà informazioni sulle immagini trascinate al server.

Diamo un'occhiata a main.js

$(funzione() (
$("#img_target")
.bind("dragenter", funzione(evento) (
$(this).addClass("drop_here");
restituire falso;
})
.bind("dragleave", funzione(evento) (
restituire falso;
})
.bind("dragover", funzione(evento) (
restituire falso;
})
.bind("rilascia", funzione(evento) (
$(this).removeClass("drop_here");
var srcRegex = /src=\"([^\s]+)\"/ig;
var data = event.originalEvent.dataTransfer.getData("text/html");
var img_data = srcRegex.exec(dati);
$.post("upload.php", ("file_url":img_data), funzione(res) (
var risposta = eval("(" + res + ")");
$("#immagini").append($(" "));
});
restituisce vero;
});

Qui assegniamo i gestori agli eventi dragenter, dragleave e dragover. Tutti dovrebbero semplicemente restituire false e, per informare in qualche modo l'utente che l'immagine può essere “rilasciata”, nel gestore dragenter impostiamo la classe CSS drop_here per il blocco ricevitore.

La maggior parte del lavoro viene svolto nel gestore dell'evento drop. Quando si verifica questo evento, leggiamo le informazioni sull'oggetto "reset" e "tagliamo" il valore dell'attributo src, ad es. URL dell'immagine (righe 16-18). Le informazioni vengono trasferite nell'oggetto event.originalEvent.dataTransfer (riga 17).

Quindi formiamo una normale richiesta AJAX e passiamo l'URL trovato come parametro.

Lo script del server (upload.php) riceverà l'URL dell'immagine sul server remoto e lo caricherà. E in risposta alla richiesta AJAX, invierà il nuovo URL dell'immagine caricata.

A sua volta, il gestore della richiesta AJAX creerà un tag img e lo inserirà nel blocco immagini. Pertanto, le immagini scaricate appariranno sopra il campo di download.

Considera upload.php

define("BASE_URL", "http://localhost/tests/images-upload/");

funzione upload_da_url($url_file) (
$segmenti_url = esplode("/", $file_url);
$nome_file = urldecode(end($segmenti_url));
if (false !== $nome_file) (
$nome_file_parti = esplode(".", $nome_file);
if (in_array(strtolower(end($file_name_parts)), array("jpeg","jpg","png","gif"))) (
$destinazione=fopen("upload/".$nome_file,"w");
$fonte=fopen($url_file,"r");
$dimensione massima=300*1024;
$lunghezza=0;
while (($a=fread($source,1024))&&($length "URL del file non specificato");

if (isset($_POST["url_file"])) (
$nuovo_url = upload_da_url($_POST["file_url"]);
$res = array("url_file" => $nuovo_url);
}

echo json_encode($res);

Il principio di funzionamento è il seguente. Leggiamo l'URL dell'immagine e proviamo a scaricarla (righe 29-32).

Se l'immagine è stata caricata, salvala nella cartella di caricamento. La ricezione di un'immagine da un server remoto viene effettuata utilizzando le funzioni fread. Il file viene letto in blocchi da 1kB (righe 15-18). Questo approccio consente di interrompere il download di un file se la sua dimensione supera un limite specificato (in questo caso 300kB).

Dopo aver scaricato il file, generiamo un URL per esso e lo inviamo al browser in formato JSON.

Come puoi vedere, implementare un bootloader di questo tipo non è difficile. Ed è abbastanza comodo da usare. Naturalmente, lo svantaggio principale è il supporto del browser per HTML5, o meglio la sua mancanza

Tuttavia, se stai creando un'interfaccia per i dipendenti di un'azienda e puoi specificare il tipo di browser, è possibile utilizzare HTML5.

E in questa lezione ti mostrerò un esempio di integrazione del meraviglioso plugin Dropzone.js con il tuo sito PHP per caricare file sul server in poche righe di codice.

Dropzone.JS è una meravigliosa libreria open source scritta in Vanilla JS che fornisce un'interfaccia drag and drop per caricare file con anteprime dei file.

Innanzitutto, scarica l'ultima versione della libreria e i suoi stili:

Quindi crea una cartella di upload e i file index.php e upload.php

Il file php indice può essere quella parte del tuo codice che contiene il modulo per aggiungere materiali al sito. Nel mio esempio, creerò una pagina vuota con markup minimo e la libreria e gli stili Dropzone.js inclusi:

Come probabilmente avrai notato, abbiamo creato un modulo con l'azione upload.php, ma non abbiamo creato alcun input per allegare file e non abbiamo dichiarato l'enctype del modulo. Non ci sono errori in questo, tutto è gestito dalla stessa libreria DropzoneJS. Tutto quello che dobbiamo fare è dare al modulo una classe dropzone. Per impostazione predefinita, DropzoneJS trova tutti i moduli con questa classe e disegna automaticamente la sua interfaccia.

Puoi aprire la pagina index.php per l'esecuzione nel browser e assicurarti che la libreria funzioni come previsto. Ecco cosa ho ottenuto:

Ora creiamo un gestore di caricamento per il quale abbiamo già creato un file upload.php. Ecco un esempio del mio codice di caricamento più semplice:

Lavorare con i file scaricati

Per interagire completamente con i tuoi file, dobbiamo solo aggiungere la possibilità di manipolarli. Innanzitutto, dobbiamo aggiungere una porzione di codice per estrarre le informazioni sui file archiviati (nome e dimensione) e restituirle in formato JSON.

Per fare ciò, aggiorna il file upload.php in questo modulo (viene inserita la condizione else):

  • La funzione scandir PHP esegue la scansione della cartella dei caricamenti e restituisce un array di file o FALSE se la cartella è vuota.
  • Eseguiamo il loop del valore restituito dalla funzione scandir e lo salviamo nell'array $result. Ricorda, ignoriamo "." E ".." poiché scandir restituirà sempre "." E ".." come contenuto valido relativo alla directory corrente e precedente.
  • Forniamo le intestazioni corrette per il markup JSON e convertiamo anche l'array PHP in una stringa JSON utilizzando la funzione json_encode.
  • Ora è il momento di aggiornare index.php:

    Dropzone.options.myDropzone = ( init: function() ( thisDropzone = this; $.get("upload.php", function(data) ( $.each(data, function(key,value)( var mockFile = ( name : valore.nome, dimensione: valore.dimensione); thisDropzone.options.addedfile.call(thisDropzone, mockFile); thisDropzone.options.thumbnail.call(thisDropzone, mockFile, "uploads/"+value.name); )); )); ) );

    Cosa abbiamo fatto qui? Scopriamolo:

  • Purtroppo, abbiamo aggiunto la libreria Jquery alla nostra pagina. Questa non è realmente una necessità per DropzoneJs. Stiamo utilizzando solo la funzione JQuery $.get ajax. A tua discrezione, puoi implementare richieste simili in vue.js o qualunque cosa preferisci.
  • Abbiamo aggiunto un elemento ID (my-dropzone) al modulo. Ciò è necessario per trasferire i valori di configurazione su Dropzone. E per questo dobbiamo avere un identificatore univoco che punti ad esso. In questo modo possiamo configurare la libreria assegnando valori a Dropzone.options.myDropzone.
  • Inizializziamo la parte principale dell'editing. Quello che abbiamo fatto qui è passato una funzione per ascoltare l'evento init a Dropzone. Questo evento viene generato quando Dropzone viene inizializzato.
  • Riceviamo una serie di file da "upload.php" utilizzando ajax.
  • Crea un mockFile utilizzando i valori dal server. I MockFiles sono semplicemente oggetti JavaScript con proprietà di nome e dimensione. Quindi chiamiamo esplicitamente le funzioni Dropbox e aggiungiamo icone per portare i file esistenti nell'area di caricamento di Dropzone e crearne le miniature.
  • Se hai fatto tutto correttamente. Carica alcune immagini e ricarica la pagina del modulo. I file caricati in precedenza dovrebbero apparire automaticamente nell'area Dropzone.

    Grazie alle innovazioni di HTML5, creare interfacce Drag and Drop è diventato molto più semplice. Sfortunatamente, queste innovazioni non hanno ancora un ampio supporto da parte dei browser, ma spero che questo cambi presto (attualmente funziona con Firefox 4+, Chrome e Opera 11.10).

    Markup Devo dire subito che l'articolo è stato scritto più per i principianti che per i professionisti. Pertanto, alcuni punti verranno descritti in modo molto dettagliato.

    Per prima cosa dobbiamo creare un file HTML con il seguente contenuto:

    Per scaricarlo, trascina il file qui.

    Tutto il nostro lavoro avverrà con il contenitore dropZone. Ora aggiungiamo gli stili per il nostro documento (style.css):

    Corpo ( carattere: 12px Arial, sans-serif; ) #dropZone ( colore: #555; dimensione carattere: 18px; allineamento testo: centro; larghezza: 400px; imbottitura: 50px 0; margine: 50px automatico; sfondo: #eee ; border: 1px solido #ccc; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; ) #dropZone.hover ( background: #ddd; border-color: #aaa; ) #dropZone.error ( sfondo: #faa; colore bordo: #f00; ) #dropZone.drop ( sfondo: #afa; colore bordo: #0f0; )

    Negli stili, puoi notare tre stati per l'elemento dropZone: al passaggio del mouse, se si verifica un errore e in caso di successo.

    Caricamento dello script Ora arriviamo alla parte divertente: scrivere il codice JavaScript. Per cominciare, dobbiamo creare delle variabili, in una delle quali posizioneremo la nostra dropZone, e nella seconda indicheremo taglia massima file.

    $(document).ready(function() ( var dropZone = $("#dropZone"), maxFileSize = 1000000; // dimensione massima del file - 1 MB. ));

    Successivamente dobbiamo verificare se il browser supporta il trascinamento della selezione, per questo utilizzeremo la funzione FileReader. Se il browser non supporta il trascinamento della selezione, all'interno dell'elemento dropZone scriveremo "Non supportato dal browser!" e aggiungi la classe "errore".

    If (typeof(window.FileReader) == "unDefinito") ( dropZone.text("Non supportato dal browser!"); dropZone.addClass("errore"); )

    La prossima cosa che faremo sarà animare l'effetto del trascinamento di un file nella dropZone. Terremo traccia di queste azioni utilizzando gli eventi “ondragover” e “ondragleave”. Ma poiché questi eventi non possono essere tracciati dall'oggetto jQuery, dobbiamo accedere non solo a "dropZone", ma a "dropZone".

    DropZone.ondragover = funzione() ( dropZone.addClass("hover"); return false; ); dropZone.ondragleave = funzione() ( dropZone.removeClass("hover"); return false; );

    Ora dobbiamo scrivere un gestore eventi per l'evento "ondrop": questo è l'evento in cui il file trascinato viene rilasciato. In alcuni browser, quando si trascinano i file nella finestra del browser, questi si aprono automaticamente, affinché ciò non accada è necessario annullare il comportamento standard del browser. Dobbiamo anche rimuovere la classe “hover” e aggiungere la classe “drop”.

    DropZone.ondrop = funzione(evento) ( event.preventDefault(); dropZone.removeClass("hover"); dropZone.addClass("drop"); );

    File Var = event.dataTransfer.files; if (file.size > maxFileSize) ( dropZone.text("Il file è troppo grande!"); dropZone.addClass("errore"); return false; )

    Ora dobbiamo scrivere una richiesta AJAX che invii il nostro file al gestore. Per creare Richiesta AJAX utilizzeremo l'oggetto XMLHttpRequest. Aggiungiamo due gestori eventi per l'oggetto XMLHttpRequest: uno mostrerà l'avanzamento del download del file e il secondo mostrerà il risultato del download. Specificheremo il file upload.php come gestore.

    Var xhr = new XMLHttpRequest(); xhr.upload.addEventListener("progress", uploadProgress, false); xhr.onreadystatechange = stateChange; xhr.open("POST", "/upload.php"); xhr.setRequestHeader("X-FILE-NAME", file.name); xhr.invia(file);

    Ora diamo un'occhiata all'avanzamento del download e alle funzioni dei risultati del download. Non c'è nulla di complicato nella funzione "uploadProgress", solo semplici calcoli.

    Funzione uploadProgress(evento) ( var percent = parseInt(event.loaded / event.total * 100); dropZone.text("Caricamento: " + percent + "%"); )

    Nella funzione "stateChange", dobbiamo verificare se il processo di caricamento è stato completato e, in tal caso, dobbiamo verificare se si sono verificati errori. Il codice della richiesta andata a buon fine è “200”; se il codice è diverso da questo significa che si è verificato un errore.

    Funzione stateChange(event) ( if (event.target.readyState == 4) ( if (event.target.status == 200) ( dropZone.text("Caricamento completato con successo!"); ) else ( dropZone.text(" Si è verificato un errore!"); dropZone.addClass("errore"); ) ) )

    La parte JavaScript è completata.

    Parte server Tutto ciò che ci rimane è scrivere un semplice gestore che salverà il file nella posizione di cui abbiamo bisogno. Non andrò troppo in profondità nella scrittura del gestore, ma fornirò solo un piccolo esempio in PHP.

    Questo è tutto, spero che l'articolo ti sia stato utile.

    È possibile scaricare i file sorgente