HTML5: nalaganje datotek s funkcijo povleci in spusti. Čudovit obrazec AJAX za nalaganje datotek Html5 nalaganje datotek z vlečenjem

05.05.2024 OS

Nadaljujemo z ustvarjanjem prenosa povleci in spusti, danes pa bomo napisali naš strežnik in začeli pisati kodo JavaScript.

V zadnjem članku smo napisali datoteko index.html in sloge zanjo. Danes bomo napisali strežnik, ki bo prenesel datoteke in poslal informacije o njih nazaj v skript, a najprej se pogovorimo o tem, kakšno datotečno strukturo bomo imeli:

  • .htaccess
  • index.html
  • style.css
  • upload.php
  • nalaganja

Z datotekama index.html in style.css je vse jasno. Enostavno nastavimo kodiranje v datoteki .htaccess, da ni težav.

AddDefaultCharset UTF-8

Datoteka upload.php bo naložila datoteke na strežnik v mapo za nalaganje.

Pa začnimo s php. Če želite to narediti, odprite datoteko upload.php in napišite naslednje:

Na začetek datoteke napišemo glavo Content-Type, da brskalniku sporočimo, da bo prejel json. Nato ustvarimo prazno matriko $uploaded in preverimo, ali sploh obstajajo datoteke. Če je odgovor pritrdilen, jih pregledamo in naložimo v naš imenik za nalaganje ter zapolnimo glavno matriko $uploaded s podmatri, ki bodo vsebovale informacije o datotekah. V našem primeru je to ime datoteke in njena lokacija. Nazadnje našo matriko pretvorimo v json in jo izdamo. Kot lahko vidite, strežnik sploh ni zapleten.

Zdaj pa pojdimo na datoteko index.html


Povlecite datoteke sem

(funkcija() (
var dropzone = document.getElementById("dropzone");
dropzone.ondragover = funkcija() (
this.className = "dropzone dragover";
this.innerHTML = "Spusti miško";
vrni false;
};

Dropzone.ondragleave = funkcija() (


vrni false;
};

Dropzone.ondrop = funkcija(e) (
this.className = "dropzone";
this.innerHTML = "Povlecite datoteke sem";
e.preventDefault();
};
})();

Se spomnite razreda .dragover, ki smo ga napisali v prejšnjem članku, in rekel sem, da bo uporabljen, ko bo nad našim blokom kakšna datoteka? To je dejansko tisto, kar smo zdaj storili. Ko se neka datoteka pojavi nad blokom, se sproži dogodek ondragover, kjer preprosto dodamo naš razred .dragover in spremenimo besedilo v "Spusti miško". Ko miško z datoteko premaknemo stran od našega bloka, se sproži dogodek ondragleave, kjer vse vrnemo na prvotno mesto. Ko oseba »spusti« datoteko v naš blok, se sproži dogodek ondrop. Tam spet spremenimo vse, kot je bilo na začetku, sicer bo razred .dragover zamrznil in prekličemo privzeto vedenje. Če tega ne storimo, se bo naša datoteka preprosto odprla v brskalniku, česar pa ne želimo.

Lep pozdrav vsem! V tem članku želim govoriti o več svojih poskusih s HTML5. Začel bom od daleč. Vsi moramo občasno delati z različnimi spletnimi vmesniki in pogosto imamo občutek, da bi to delo lahko organizirali bolj učinkovito.

Morda so v nekaterih primerih krivi razvijalci storitev, pogosto pa je težava v omejitvah, ki jih postavljajo brskalniki. Razmislimo o nalaganju datotek na strežnik. V večini primerov se vam prikaže standardno polje z gumbom za izbiro datoteke iz vašega računalnika in/ali polje, v katerem lahko določite URL datoteke, ki se nahaja nekje v internetu.

Zaenkrat se ne bomo dotaknili prenosa datotek iz lokalnega računalnika, nameravam objaviti ločeno objavo na to temo, poglejmo prenos z oddaljenega strežnika.

Težave se začnejo že pri prvem koraku. Tudi če jasno razumete, kje iskati URL, in dobro uporabljate orodja, kot je požarni hrošč, bo še vedno potrebnih nekaj klikov, da dobite pravi naslov. Veliko bolj priročno bi bilo preprosto povleči želeno sliko iz enega okna brskalnika v drugega.

V tem članku bom prikazal primer izvedbe takega vmesnika. Če želite, si lahko ogledate, kako deluje na demo strani ali .

Opomba! Ta primer deluje samo v brskalniku Google Chrome. V teoriji Firefox in Safari podpirata vse potrebne tehnologije, vendar jih še nisem ugotovil. V glavnem sem vzel slike iz Wikipedije kot objekte za vlečenje. Opaženih je bilo več težav, povezanih z nelatiničnimi znaki v URL-jih slik, a da primera ne bi preobremenil s preverjanji in transformacijami, sem jih pustil takšne, kot so.

Načelo delovanja

Standard HTML5 nudi podporo za vlečenje in spuščanje predmetov strani. Mimogrede, že sem pokazal primer najpreprostejše izvedbe D&D - Drag & Drop z uporabo HTML5. Poleg tega obstaja kar nekaj knjižnic JavaScript, ki izvajajo podporo za D&D.

Toda tukaj je pomembno razumeti, da če morate "povleči" slike iz virov tretjih oseb, potem ne boste mogli uporabljati knjižnic. Ker svoje kode JS ne boste mogli dodati na stran nekoga drugega. In da prenesemo sliko, moramo dobiti njen URL, tj. Brskalnik mora prenesti tudi svoje parametre skupaj z vlečenim predmetom (na primer atribut src slike ali celotno oznako img).

V tem primeru lahko na naši strani ustvarimo »sprejemnik« slik. To bo običajni div z dodeljenim obdelovalcem dogodka drop. Če uporabnik "spusti" sliko nad tem divom, bo poklican upravljalnik in v prvem parametru bo prejel objekt, ki vsebuje informacije o sliki, ki jo vlečete.

Izvedba

Začnimo z našo prijavno stranjo.

Nalaganje slik


Vsebuje dva bloka: slike – tukaj bomo prikazali prenesene slike in img_target – v ta blok morate povleči slike. Na dnu strani povežemo knjižnico jQuery in skripto main.js, ki bo na strežnik pošiljala informacije o vlečenih slikah.

Poglejmo main.js
$(funkcija() (
$("#img_target")
.bind("dragenter", funkcija(dogodek) (
$(to).addClass("spusti_sem");
vrni false;
})
.bind("dragleave", funkcija(dogodek) (

vrni false;
})
.bind("dragover", funkcija(dogodek) (
vrni false;
})
.bind("drop", funkcija(dogodek) (
$(this).removeClass("spusti_sem");
var srcRegex = /src=\"([^\s]+)\"/ig;
var data = event.originalEvent.dataTransfer.getData("text/html");
var img_data = srcRegex.exec(podatki);
$.post("upload.php", ("file_url":img_data), function(res) (
var response = eval("(" + res + ")");
$("#slike").append($(""));
});
vrni resnico;
});
});
Tukaj dodelimo upravljalce dogodkom dragenter, dragleave in dragover. Vse bi morale preprosto vrniti false in, da bi nekako obvestili uporabnika, da je sliko mogoče »spustiti«, smo v upravljalniku dragenterja za sprejemni blok nastavili razred CSS drop_here. Večina dela je opravljenega v obdelovalniku dogodkov padca. Ko pride do tega dogodka, preberemo informacije o objektu “reset” in “izrežemo” vrednost atributa src, tj. URL slike. Informacije se prenesejo v objekt event.originalEvent.dataTransfer.

Nato oblikujemo običajno zahtevo AJAX in posredujemo najdeni URL kot parameter. Strežniška skripta (upload.php) bo prejela URL slike na oddaljenem strežniku in jo naložila. In kot odgovor na zahtevo AJAX bo poslal nov URL naložene slike. Po drugi strani bo upravljalnik zahtev AJAX ustvaril oznako img in jo vstavil v blok slik. Tako se bodo prenesene slike pojavile nad poljem za prenos.

Razmislite o upload.php

Načelo delovanja je naslednje. Preberemo URL slike in jo poskušamo prenesti. Če je slika naložena, jo shranite v mapo za nalaganje. Prejemanje slike z oddaljenega strežnika se izvaja s funkcijami fread. Datoteka se bere v blokih po 1 kB. Ta pristop vam omogoča, da prekinete prenos datoteke, če njena velikost preseže določeno omejitev (v tem primeru 300 kB).

Po prenosu datoteke ustvarimo URL zanjo in jo pošljemo brskalniku v formatu JSON. Kot lahko vidite, implementacija takšnega zagonskega nalagalnika ni težka. In je zelo priročen za uporabo. Seveda je glavna pomanjkljivost podpora HTML5 s strani brskalnikov ali bolje rečeno pomanjkanje le-teh. Če pa ustvarjate vmesnik za zaposlene v podjetju in lahko določite vrsto brskalnika, potem lahko uporabite HTML5.

V tej lekciji vam bom pokazal primer integracije čudovitega vtičnika Dropzone.js z vašim spletnim mestom PHP za nalaganje datotek na strežnik v le nekaj vrsticah kode.

Dropzone.JS je čudovita odprtokodna knjižnica, napisana v vanilije JS, ki vam ponuja vmesnik povleci in spusti za nalaganje datotek s predogledi datotek.

Najprej prenesite najnovejšo različico knjižnice in njenih slogov:

Nato ustvarite mapo za nalaganje in datoteki index.php in upload.php

Indeksna datoteka php je lahko tisti del vaše kode, ki vsebuje obrazec za dodajanje gradiva na spletno mesto. V svojem primeru bom ustvaril prazno stran z minimalnimi oznakami ter vključeno knjižnico in slogi Dropzone.js:

Kot ste verjetno opazili, smo ustvarili obrazec z dejanjem upload.php, vendar nismo ustvarili nobenih vnosov za pripenjanje datotek in nismo deklarirali enctype obrazca. V tem ni nobene napake, vse ureja sama knjižnica DropzoneJS. Vse kar moramo storiti je, da obrazcu dodelimo razred dropzone. DropzoneJS privzeto najde vse obrazce s tem razredom in samodejno nariše njihov vmesnik.

Stran index.php lahko odprete za izvajanje v brskalniku in se prepričate, da knjižnica deluje, kot je predvideno. Evo, kaj sem dobil:

Zdaj pa ustvarimo upravljalnik za nalaganje, za katerega smo že ustvarili datoteko upload.php. Tukaj je primer moje najpreprostejše kode za nalaganje:

Delo s prenesenimi datotekami

Za popolno interakcijo z vašimi datotekami moramo samo dodati možnost manipulacije z njimi. Najprej moramo dodati del kode za pridobivanje informacij o shranjenih datotekah (ime in velikost) in jih vrniti v formatu JSON.

Če želite to narediti, posodobite datoteko upload.php na ta obrazec (vstavljen je pogoj else):

  • Funkcija PHP scandir pregleda mapo za nalaganje in vrne niz datotek ali FALSE, če je mapa prazna.
  • Vrnemo se skozi vrnjeno vrednost iz funkcije scandir in jo shranimo v matriko $result. Ne pozabite, ignoriramo "." In ".." ker bo scandir vedno vrnil "." In »..« kot veljavna vsebina, povezana s trenutnim in prejšnjim imenikom.
  • Izpišemo pravilne glave za oznako JSON in tudi pretvorimo matriko PHP v niz JSON s funkcijo json_encode.
  • Zdaj je čas za posodobitev index.php:

    Dropzone.options.myDropzone = ( init: function() ( thisDropzone = this; $.get("upload.php", function(data) ( $.each(data, function(key,value)( var mockFile = ( name : value.name, size: value.size ); thisDropzone.addedfile.call(thisDropzone, mockFile)); ;

    Kaj smo naredili tukaj? Ugotovimo:

  • Žal, na našo stran smo dodali knjižnico Jquery. To za DropzoneJs pravzaprav ni nujno. Uporabljamo samo funkcijo JQuery $.get ajax. Po lastni presoji lahko podobne zahteve implementirate v vue.js ali karkoli želite.
  • V obrazec smo dodali ID element (my-dropzone). To je potrebno za prenos konfiguracijskih vrednosti v Dropzone. In za to moramo imeti edinstven identifikator, ki kaže nanj. Na ta način lahko konfiguriramo knjižnico tako, da dodelimo vrednosti Dropzone.options.myDropzone.
  • Inicializirajmo glavni del urejanja. Kar smo naredili tukaj, je posredovanje funkcije za poslušanje inicialnega dogodka v Dropzone. Ta dogodek se sproži, ko je Dropzone inicializiran.
  • Prejmemo niz datotek iz »upload.php« z uporabo ajaxa.
  • Ustvarite mockFile z uporabo vrednosti iz strežnika. MockFiles so preprosto objekti JavaScript z lastnostmi imena in velikosti. Nato izrecno pokličemo funkcije Dropboxa in dodamo ikone, da prenesemo obstoječe datoteke v območje za nalaganje Dropzone in ustvarimo njihove sličice.
  • Če ste naredili vse pravilno. Naložite nekaj slik in znova naložite stran obrazca. Prej naložene datoteke bi se morale samodejno prikazati v območju Dropzone.

    Pripravila: Evgeny Ryzhkov in Egor Skornyakov Datum objave: 12.6.2011

    Naloga

    Uporabniku omogočite nalaganje datotek na strežnik tako, da jih povlečete na primer z namizja. Poleg tega bi bilo mogoče povleči in spustiti več datotek hkrati.

    rešitev

    Poglejmo demo primer. Primer najdete v arhivu. Preverjeno:

    • IE 6-9
    • Firefox 3.6-4
    • Opera 11.1
    • Chrome
    • Safari 5

    Naj vas opozorim, da je v tem primeru označeno!= deluje:

    • IE, vključno z različico 9, ne podpira File API (stara izvedba);
    • Firefox 3.6+ podpira vse, kar potrebujete. Za starejše različice - stara izvedba;
    • Opera 11.1 podpira File API, vendar ne podpira DnD;
    • Chrome od različice 10 naprej podpira vse, kar potrebujete;
    • Safari podpira vse, kar potrebujete od različice 6.

    Kakšna je korist od tega v tem primeru? Uporabniki običajnih brskalnikov dobijo bolj priročna spletna mesta.

    Kaj prenesti:
    • vtičnik (12Kb nestisnjen)
    Hiter začetek

    Povežemo skripte in dodamo type =file z . Če brskalnik ne podpira zahtevanega nabora API-jev, bo uporabnik lahko naložil fotografijo na staromoden način. Da bo imel možnost dodati več fotografij, bomo dinamično dodali gumb “+”, ki bo dodal vnosna polja type=file. Za te namene ID polja vsebuje 0 za lažjo organizacijo pravilnih imen dodanih polj.

    ...

    Pri brskalnikih, ki podpirajo Dnd in File API, lahko popolnoma skrijete ali odstranite polja type=file.

    Kako deluje

    Če ne greste preveč v podrobnosti, lahko načelo delovanja prikažete v obliki podobnega diagrama:

  • (DnD API) vse se začne, ko uporabnik spusti pritisnjen gumb miške - sproži se dogodek drop;
  • (API DnD) pridobi objekt DataTransfer iz dogodka padca;
  • (File API) s klicem DataTransfer.files dobimo FileList – seznam datotek, ki jih je uporabnik povlekel v območje za prenos;
  • (File API) s pregledovanjem vseh datotek preberemo njihovo vsebino s pomočjo predmeta FileReader;
  • (File API), ki kliče FileReader.readAsDataURL(../../../collect/js-plugins/ui/file) vsakič, ko je naslednja datoteka uspešno prebrana, oblikujemo podatkovni objekt URL. Ko je popolnoma oblikovan, se bo zgodil dogodek onloadend objekta FileReader;
  • ko prejmemo objekt data:URL, lahko te podatke nadomestimo v src in jih prikažemo ter pošljemo podatke v binarni obliki na strežnik;
  • (XMLHttpRequest 2) podatke pošiljamo asinhrono, z novostmi druge različice protokola XMLHttpRequest pa prejemamo podatke o statusu prenosa (progress event), kar nam omogoča obveščanje uporabnika.
  • Fine Uploader Plugin

    posodobitev: 18.09.12 avtor Andrey Kosyak.

    Precej priročen vtičnik js za nalaganje datotek na strežnik. Napisano v čistem JS. Sestavljen je iz strežniškega dela (v več jezikih) in odjemalskega dela (JS in CSS).

    NE uporablja Flash in poljubna ogrodja.

    Fineuploader uporablja objekt XMLHttpRequest za prenos datotek z vrstico napredka za sodobne brskalnike, za vse smeti pa se uporablja dobra stara metoda iframe.

    Seznamimo se:
    • Projekt na GitHubu
    • Izvorni demo
    • Dokumentacija (v angleščini)

    Preverjeno:

    • IE 7-9
    • Firefox 3.6+
    • Opera 10.6+
    • Chrome
    • Safari 4+
    Hiter začetek

    Delovanje vtičnika je treba preveriti izključno s strežnika (lokalno je v redu). V primeru bom uporabil strežniški del v PHP.

    Pred prvim zagonom morate pripraviti tla:

      Na lokalnem strežniku bo skript najprej zahteval povečanje vrednosti parametrov post_max_size in upload_max_filesize. Odprite datoteko php.ini, poiščite te parametre in nastavite vrednosti na >= 10M. Na pravem strežniku ta element najverjetneje ne bo potreben.

      • če testiramo na spletnem strežniku, potem nastavimo dovoljenja na 777
      • če testiramo lokalno, potem v lastnostih mape počistimo potrditveno polje »samo za branje« (lahko deluje tudi brez tega)
    • iz mape /server vtičnika vzamemo datoteko php.php. V njem je v prvem bloku komentarjev zapisano, katere vrstice je treba izluščiti iz komentarjev, da se razred inicializira. Dodajte takoj za blokom komentarjev:

      // dovoljene končnice datotek $allowedExtensions = array(); // največja velikost datoteke $sizeLimit = 10 * 1024 * 1024; // inicializacija razreda $uploader = new qqFileUploader($allowedExtensions, $sizeLimit); // tukaj morate določiti pot do mape /uploads $result = $uploader->handleUpload("../uploads/"); // vrni odgovor po shranjevanju datoteke echo htmlspecialchars(json_encode($result), ENT_NOQUOTES);

    Povezujemo skript vtičnika in sloge:

    Za uporabo nalagalnika datotek omogočite JavaScript.

    Inicializacija JS:

    Window.onload = function())( var uploader = new qq.FileUploader(( element: document.getElementById("file-uploader1"), action: "php/upload.php" // pot do strežniške strani vtičnika ));

    Najprej morate seveda ustvariti element, ki bo "ujel" datoteko. Poleg tega bomo v ta element postavili oznako span za prikaz sporočil o statusu nalaganja in vnos s tipom mapa, da ne bi omejevali izbire datotek na povleci in spusti, ampak tudi omogočili uporabnikom, da izberejo datoteko s klikom na to označeno območje. Končna oblika takšne strukture je predstavljena spodaj.

    Kliknite tukaj ali povlecite in spustite datoteko za nalaganje.

    CSS za to HTML koda je nepomembna, razen zasnove polja vnos:

    #datoteka(širina:100%; višina:100%; prikaz:blok; položaj:absolutno; zgoraj:0; levo:0; motnost:0,01; )

    Opisujemo tudi dva razreda, ki bosta, ko ju dodamo v območje »zajemanja« datoteke, signalizirala uspešen prenos datoteke ali napako, če do nje pride:

    #drop-zone.success(barva-ozadje:#2ecc71;) #drop-zone.error(barva-ozadje:#e74c3c;)

    Zdaj lahko nadaljujemo s pisanjem »akcije« naše strani. Najprej zapišimo v spremenljivke sklice na objekte, do katerih bomo pogosto dostopali:

    Var dropZone = document.getElementById("drop-zone"); var msgContainer = document.querySelector("#drop-zone .text");

    Po tem se bomo znebili privzetih dogodkov, ko kazalec zadene naše območje za sprejem datoteke, kot sledi:

    Var eventClear = funkcija (e) ( e.stopPropagation(); e.preventDefault(); ) dropZone.addEventListener("dragenter", eventClear, false); dropZone.addEventListener("dragover", eventClear, false);

    DropZone.addEventListener("drop", funkcija (e) ( if(!e.dataTransfer.files) return; e.stopPropagation(); e.preventDefault(); sendFile(e.dataTransfer.files); ), false); document.getElementById("file").addEventListener("sprememba", funkcija (e) ( sendFile(e.target.files); ), false);

    V obeh primerih se dogodek konča s klicem funkcije sendFile, v katerega se prenese od uporabnika prejeta datoteka.

    Ta funkcija je odgovorna za prenos datoteke na strežnik. Njegov opis si lahko ogledate spodaj.

    Var sendFile = function(file) ( // odstranite razrede stanja, ki bi lahko bili dodani // če je uporabnik že poskusil nekaj prenesti dropZone.classList.remove("uspeh"); dropZone.classList.remove("error") ; / / preveri z uporabo regularnega izraza za vrsto datoteke // (v primeru je dovoljeno naložiti samo slike) var re = /(.jpg|.jpeg|.bmp|.gif|.png)$/i ; exec(file.name)) ( msgConteiner.innerHTML = "Neveljavna oblika datoteke!"; dropZone.classList.remove("uspeh"); dropZone.classList.add("error"); ) else ( var fd = new FormData ( ); // ustvarjanje obrazca fd.append("upfile", file); // dodajanje datoteke v obrazec za pošiljanje var xhr.upload.onprogress; xhr.onreadystatechange = statChange; // pošiljanje na strežnik )

    Kot ste morda opazili, sta pred pošiljanjem podatkov na strežnik nastavljena tudi dva dogodka, od katerih je prvi odgovoren za prikaz poteka prenosa, drugi pa za obveščanje o rezultatu prenosa. Delujejo na naslednji način:

    Var showProgress = function(e) ( if (e.lengthComputable) ( // izračuna odstotek nalaganja var percent = Math.floor((e.loaded / e.total) * 100); // prikaže trenutni odstotek msgConteiner.innerHTML = " Nalaganje ... ("+ odstotek" )); var statChange = function (e) ( if (e.target.readyState == 4) ( // po zaključku obdelave zahteve do strežnika if (e.target.status == 200) ( // če je bila zahteva uspešna msgConteiner.innerHTML = "Nalaganje uspešno!"; dropZone.classList.add("success");innerHTML = this.responseText) else ( // else msgConteiner.innerHTML = "Prišlo je do napake!"; dropZone.classList.remove("uspeh"); dropZone.classList.add("error" ) )

    Zadnja faza bo obdelava podatkov, ki jih prejme strežnik.