Laster opp filer med AJAX

Jeg kan ikke synes å nå slutten på de morsomme tingene du kan gjøre med nye webteknologier. I dag skal jeg vise deg hvordan du gjør noe som - til siste stund - har vært nesten uten sidestykke: opplasting av filer via AJAX.

Åh, det har vært hacks; men hvis du er som meg, og føl deg skitten hver gang du skriver iframe, du kommer til å like dette mye. Bli med meg etter hoppet!

Leter du etter en rask løsning?

Hvis du er ute etter en rask løsning, er det en flott samling av filopplastingskript og -programmer på Envato Market.ja

Denne HTML5-filopplasteren er spesielt smart - du kan legge til filer enkelt ved å dra og slippe dem eller klikke. Alle filer vil bli lastet opp via AJAX eller kan legges til i et skjema, og filer kan omdøpes før opplasting. En flott, rask løsning hvis det er det du leter etter!


Hvorfor får vi ikke de dårlige nyhetene med?

Dette virker ikke i alle nettlesere. Men med noen progressiv forbedring (eller hva det nåværende buzzword er), har vi en opplastingsside som vil fungere helt tilbake til IE6 (om enn uten AJAXy-biter).

Vår AJAX-opplasting vil fungere så lenge som FormData er tilgjengelig; Ellers vil brukeren få en vanlig opplasting.

Det er tre hovedkomponenter til prosjektet vårt.

  • De flere attributt på filen inngang element.
  • De Filereader objekt fra den nye fil-APIen.
  • De FormData objekt fra XMLHttpRequest2.

Vi bruker flere attributt til å tillate brukeren å velge flere filer for opplasting (flere filopplasting vil fungere normalt selv om FormData er ikke tilgjengelig). Som du vil se, Filereader tillater oss å vise brukerens miniatyrbilder av filene de laster opp (vi venter bilder).

Ingen av våre tre funksjoner fungerer i IE9, så alle IE-brukere får en vanlig opplastingsopplevelse (selv om jeg forstår støtte for 'FileReader', er tilgjengelig i IE10 Dev Preview 2). Filereader Fungerer ikke i den nyeste versjonen av Safari (5.1), slik at de ikke får miniatyrbildene, men de får AJAX-opplastingen og bekreftelsesmeldingen. Endelig har Opera 10,50 Filereader støtte, men ikke FormData støtte, så de får miniatyrer, men vanlige opplastinger.

Med det ut av veien, la oss få koding!


Trinn 1: Markering og styling

La oss begynne med noen grunnleggende oppslag og styling. Selvfølgelig, dette er ikke hoveddelen av denne opplæringen, jeg vil ikke behandle deg som en nybegynner.

HTML-koden

    HTML5-fil-API    

Last opp bildene dine

Ganske grunnleggende, eh? Vi har et skjema som legger inn på upload.php, som vi ser på i et sekund, og et enkelt inngangselement av typen fil. Legg merke til at den har boolsk flere attributt, som tillater brukeren å velge flere filer samtidig.

Det er egentlig alt der er å se her. La oss gå videre.

CSS

kropp font: 14px / 1.5 helvetica-neue, helvetica, arial, san-serif; padding: 10px;  h1 margin-top: 0;  #main width: 300px; margin: auto; bakgrunn: #ececec; polstring: 20px; grense: 1px solid #ccc;  # bilde-liste listestil: none; margin: 0; padding: 0;  # bilde-liste li bakgrunn: #fff; grense: 1px solid #ccc; tekst-Justering: center; padding: 20 piksler; margin-bottom: 19px;  # bilde-liste li img bredde: 258px; vertikaljustering: midt; grense: 1px solid # 474747; 

Absolutt ingen shockers her.


Trinn 2: PHP

Vi må også kunne håndtere filopplastingene på baksiden, så la oss dekke det neste.

upload.php

 $ feil) if ($ error == UPLOAD_ERR_OK) $ name = $ _FILES ["images"] ["name"] [$ key]; move_uploaded_file ($ _FILES ["images"] ["tmp_name"] [$ key], "opplastinger /". $ _FILES ['images'] ['name'] [$ key]);   ekko "

Opplastede bilder på en vellykket måte

";

Husk at disse var de første linjene i PHP jeg hadde skrevet inn i løpet av ett år (jeg er en Ruby-fyr). Du bør nok gjøre litt mer for sikkerhet; Vi sørger imidlertid bare for at det ikke er noen opplastingsfeil. Hvis det er tilfelle, bruker vi den innebygde move_uploaded_file å flytte den til en opplastinger mappe. Ikke glem å sørge for at mappen er skrivbar.

Så, akkurat nå, bør vi ha et fungerende opplastingsskjema. Du velger et bilde (flere, hvis du vil og nettleseren lar deg), klikker du på ?Last opp filer!? knappen, og du får meldingen ?Opplastede bilder på en vellykket måte.?

Slik ser vårt mini-prosjekt ut så langt:

Men kom igjen, det er 2011: vi vil ha mer enn det. Du vil legge merke til at vi har koblet opp jQuery og en upload.js fil. La oss sprekke som åpnes nå.


Trinn 3: JavaScript

La oss ikke kaste bort tid: her går vi!

(funksjon () var input = document.getElementById ("bilder"), formdata = false; if (window.FormData) formdata = ny FormData (); document.getElementById ("btn"). style.display = "none "; ();

Her begynner vi med. Vi lager to variabler: inngang er vårt filinngangselement; formdata vil bli brukt til å sende bildene til serveren hvis nettleseren støtter det. Vi initialiserer den til falsk og sjekk deretter for å se om nettleseren støtter FormData; Hvis det gjør det, oppretter vi en ny FormData gjenstand. Også, hvis vi kan sende inn bildene med AJAX, trenger vi ikke? Last opp bilder !? knappen, slik at vi kan gjemme det. Hvorfor trenger vi ikke det? Vel, vi skal automatisk laste opp bildene umiddelbart etter at brukeren har valgt dem.

Resten av JavaScript vil gå inn i din anonyme selvoppringningsfunksjon. Deretter lager vi en liten hjelperfunksjon som viser bildene når nettleseren har dem:

funksjon showUploadedItem (kilde) var list = document.getElementById ("bildeliste"), li = document.createElement ("li"), img = document.createElement ("img"); img.src = kilde; li.appendChild (img); list.appendChild (li); 

Funksjonen tar en parameter: Bildekilden (vi får se hvordan vi får det snart). Deretter finner vi bare listen i vår markering og lager en liste og bilde. Vi setter bildekilden til kilden vi mottok, legg bildet i listeposten, og sett listeposten i listen. voila!

Deretter må vi faktisk ta bildene, vise dem og laste dem opp. Som vi har sagt, gjør vi dette når OnChange Hendelsen avfyres på inngangselementet.

hvis (input.addEventListener) input.addEventListener ("endre", funksjon (evt) var i = 0, len = this.files.length, img, leser, fil; document.getElementById ("respons"). innerHTML = "Uploading" for (; i < len; i++ )  file = this.files[i]; if (!!file.type.match(/image.*/))    , false); 

Vi trenger ikke å bekymre oss for IEs proprietære hendelsesmodell, fordi IE9 + støtter standard addEventListener-funksjonen.

Det er mer, men la oss starte med dette. For det første trenger vi ikke å bekymre oss for IEs proprietære arrangementsmodell, fordi IE9 + støtter standarden addEventListener funksjon (og IE9 og ned støtter ikke våre nye funksjoner).

Så, hva vil vi gjøre når brukeren har valgt filer? Først oppretter vi noen variabler. Den eneste viktige en akkurat nå er len = this.files.length. Filene som brukeren har valgt, vil være tilgjengelig fra objektet this.files. Akkurat nå er vi bare opptatt av lengde eiendom, slik at vi kan løse over filene?

? som er akkurat det vi gjør neste gang. Inne i vår loop, setter vi gjeldende fil til fil for enkel tilgang. Neste ting vi gjør er å bekrefte at filen er et bilde. Vi kan gjøre dette ved å sammenligne type eiendom med et regulært uttrykk. Vi leter etter en type som starter med? Bilde? og etterfølges av noe. (Double-bang foran konverterer bare resultatet til en boolsk.)

Så, hva gjør vi hvis vi har et bilde på våre hender?

hvis (window.FileReader) leser = ny FileReader (); reader.onloadend = funksjon (e) showUploadedItem (e.target.result); ; reader.readAsDataURL (fil);  hvis (formdata) formdata.append ("images []", fil); 

Vi ser etter om nettleseren støtter å opprette Filereader objekter. Hvis det gjør det, oppretter vi en.

Slik bruker vi en Filereader objekt: Vi skal passere våre fil protestere mot reader.readAsDataURL metode. Dette skaper en datalogg for det opplastede bildet. Det virker ikke slik du kan forvente, skjønt. Data-url sendes ikke tilbake fra funksjonen. I stedet vil dataadressen være en del av et hendelsesobjekt.

Med det i tankene må vi registrere en funksjon på reader.onloadend begivenhet. Denne funksjonen tar et hendelsesobjekt, hvorved vi får dataadressen: den er på e.target.result (ja, e.target er den leser objekt, men jeg hadde problemer når jeg brukte leser i stedet for e.target inne i denne funksjonen). Vi skal bare passere denne dataloggen til vår showUploadedItem funksjon (som vi skrev over).

Deretter sjekker vi etter formdata gjenstand. Husk, hvis nettleseren støtter FormData, formdata vil være en FormData gjenstand; ellers vil det være falsk. Så, hvis vi har en FormData objekt, vi skal ringe føyer metode. Formålet med a FormData objektet er å holde verdier som du sender inn via et skjema så føyer Metoden tar bare en nøkkel og en verdi. I vårt tilfelle er nøkkelen vår Bilder[]; Ved å legge til firkantede parenteser til slutt, sørger vi for hver gang vi føyer En annen verdi, vi tilføyer faktisk det til det arrayet, i stedet for å overskrive bilde eiendom.

Vi er nesten ferdige. I vår forløp har vi vist hver av bildene for brukeren og lagt dem til formdata gjenstand. Nå må vi bare laste opp bildene. Utenfor til loop, her er det siste stykket av vårt puslespill:

hvis (formdata) $ .ajax (url: "upload.php", skriv: "POST", data: formdata, processData: false, contentType: falsk, suksess: funksjon (res) document.getElementById ) .innerHTML = res;); 

Igjen må vi sørge for at vi har FormData Brukerstøtte; hvis vi ikke gjør det, laster du opp filer !? knappen vil være synlig, og det er hvordan brukeren vil laste opp bildene. Men hvis vi har FormData støtte, vi tar vare på opplasting via AJAX. Vi bruker jQuery til å håndtere alle rariteten til AJAX over nettlesere.

Du er sikkert kjent med jQuery's $ .ajax Metode: Du sender det til et alternativobjekt. De url, type, og suksess egenskaper bør være åpenbare. De data Eiendommen er vår formdata gjenstand. Legg merke til disse processData og innholdstype eiendommer. Ifølge jQuerys dokumentasjon, processData er ekte som standard, og vil behandle og transformere dataene i en spørringsstreng. Vi ønsker ikke å gjøre det, så vi satte dette til falsk. Vi setter også inn innholdstype til falsk for å sikre at data kommer til serveren som vi forventer det.

Og det er det. Nå, når brukeren laster siden, ser de dette:

Og etter at de har valgt bildene, ser de dette:

Og bildene har blitt lastet opp:


Det er en Wrap!

Opplasting av filer via AJAX er ganske kult, og det er flott at disse nye teknologiene støtter det uten behov for lange hack. Hvis du har noen spørsmål om hva vi har gjort her, klikk på disse kommentarene! Takk så mye for å lese!

Og hvis du fortsatt trenger hjelp med dette eller andre kodingsproblem, kan du finne støtte på Envato Studio.

Lær JavaScript: Den komplette veiledningen

Vi har bygget en komplett guide for å hjelpe youjelearn JavaScript, enten du bare er i gang som webutvikler eller du vil utforske mer avanserte emner.