ES sapratu (meklējot sevi) ka tur ir daudz demos un konsultācijas, kas parādīs, kā vilkt un nomest failu pārlūkā un tad padarīt to lapā. Viņi bieži dēvē par “drag-and-drop un augšupielāde”, bet tie faktiskinav augšupielādēt. Šī apmācība jums šo pēdējo soli.
Es staigāt jūs cauripiemērs, ka jūs varat spēlēt ar: velciet failu mājas lapā, un tas tiks augšupielādēti uz servera uzreiz.
uzdevumi#
Pieņemsim pārtrauktu šo procesu sadalīt konkrētos uzdevumus:
- Capture piliens notikumu un lasīt savu datu.
- Post ka binārie dati uz serveri.
- Sniegt atsauksmes par progresu augšupielādes.
- Ja vēlaties padarīt priekšskatījumu, kas tiek augšupielādēts, un tā statuss.
Lai sasniegtu visu šo, mums ir nepieciešama šāda HTML5 un kas nav HTML5 API:
Paturiet prātā, ka ne visas pārlūkprogrammas atbalsta visas šīs tehnoloģijas šodien, bet viņi kļūst tuvu. Es tikai gribēju, lai izveidotu skaidru un pilnīgu pamācību par to, kā iet uz visu vepris un augšupielādes, ka samazinājās failu.
Gala rezultāts: mēs varam nomest failu jebkurā pārlūkā, mēs priekšskatījumu un augšupielādes norisi, un tas ir slidens pieredze.

Vilkt un nomest#
Tāpat kā forewarning, vilkt un nomest, ir zināms, ka ir mazliet par killjoy. Patiesībā, tas ir murgs, bet es neatkārtošu to, kas ir bijisminētāpirms.
Mūsu piemērs ir gatavojas ļauj jums vilkt un nomest failu jebkurā pārlūkā. Lai to panāktu, ka, mums ir nepieciešams, lai pievienotu mūsu notikumu klausītājiem uzbody
vaidocumentElement
(t.i., saknes HTML mezgls). Uzklausot pardocumentElement
, this codecould be anywhere in the page, asdocumentElement
will always exist. You can only listen onbody
once the<body>
element has been encountered.
Here’s the pattern of code we need to capture the drop event on the entire document:
var doc = document.documentElement; doc.ondragover = function () { this.className = 'hover';return false; }; doc.ondragend = function () { this.className = ''; returnfalse; }; doc.ondrop = function (event) { event.preventDefault && event.preventDefault(); this.className = ''; // now do something with: var files = event.dataTransfer.files; return false; };
I’m using thehover
class so that I can toggle a tip explaining to the user that the file can be dropped on the page.
Inside thedrop
event, we can access the dropped files viaevent.dataTransfer.files
.
An Alternative to Drag and Drop#
Annoyingly, as I write this, I realise this combination of API requirements is currently only met by Chrome and Firefox. tā, taking the test fromModernizr, we can test for support and provide our alternative:
var dndSupported = function () { var div = document.createElement('div'); return ('draggable' in div) || ('ondragstart' in div &&'ondrop' in div); }; if (!dndSupported()) { // take alternative route }
Instead of drag-and-drop, we can insert a file input element (I’ve given it anid
no “augšupielādēt”), and when its value is changed, the file can be scooped in:
document.getElementById('upload').onchange = function (event){ // `this` refers to the element the event fired upon var files = this.files; };
You can see the equivalent is simply thefiles
property of theHTMLInputElement
objekts. This will give us access to the same file as theevent.dataTransfer.files
from the drop event.
Automātiski augšupielādējiet failu#
Tas ir veikls mazliet, un tas ir sāpīgi vienkāršs. Mēs izmantojam iezīme XHR2 spec: FormData
. Pēc tam, kad mēs izveidojam gadījumsFormData
, mēs varam pievienot objektus uz to:
var formData = new FormData(); for (var i = 0; i < files.length; i++) { formData.append('file', files[i]); } // now post a new XHR request var xhr = new XMLHttpRequest(); xhr.open('POST', '/upload'); xhr.onload = function () { if (xhr.status === 200) { console.log('all done: ' + xhr.status); } else { console.log('Something went terribly wrong...'); } }; xhr.send(formData);
FormData
Jā, tieši tā.†
Apskatīsim pāris galvenās lietas, kas notiek ar minēto kodu.
formData.append('file', files[i]);
Mēs nosūtām norādītos parametrus uz mūsu serveri, īpaši masīvs vērtībām saucfile
. acīmredzot, Jūs varat zvanīt to, ko jūs vēlaties, betfile
ir nosaukums jūsu serveris būs meklē, ja tā saglabā augšupielādēto failu (vai faili).
xhr.onload = function () { if (xhr.status === 200) { console.log('all done: ' + xhr.status); } else { console.log('Something went terribly wrong...'); } };
Ja jūs esat iepazinušies ar XHR, Jūs pamanīsiet mums nav klausītiesonreadystatechange
, tikaionload
- kurš ir (spēkā) ērtība funkcija, lai jūs zināt, kadreadyState
ir 4 (t.i., piekrauts!). Jums joprojām pārbaudīt un atbilstoši reaģēt uz statusa kodu pieprasījumu, lai nodrošinātu tā 200 labi, nevis 500 (Iekšējā servera kļūda) vai 404 (nav atrasts) vai kaut kas cits.
xhr.send(formData);
Jauka Triks šeit ir tas, ka XHR ir automātiski iestatīt kodējumu norīkoto datu nodošanumultipart/form-data
. Šis kodējums ļauj jūsu servera lasīt un saglabāt failus. Tas ir tāpat kā kodēšanai izmanto, kad jūs sūtīt pielikumu pa e-pastu.
Nodrošinot Atsauksmes Lietotājam#
XHR2 tagad (Flippin’ beidzot) nāk arprogress
event. Tātad, ja jūs sūtāt vai izgūšanas lielu failu, izmantojot XHR, Jūs varat pateikt lietotāju, cik tālu gar esat.
Tas ir diezgan vienkārši,. Ja jūs vēlaties, lai izsekotu progresu XHR pieprasījuma, klausītiesprogress
event. Viens Gotcha kas nozvejotas mani kādu laiku: Man vajadzēja sekot līdzi noaugšupielādēt, nevis lejupielāde. Lai to izdarītu pareizi, Jums ir nepieciešams, lai klausītos progresu attiecībā uzXHR augšupielāde objekts, kā tā:
xhr.upload.onprogress = function (event) { if (event.lengthComputable) { var complete = (event.loaded / event.total * 100 | 0); progress.value = progress.innerHTML = complete; } }; xhr.onload = function () { // just in case we get stuck around 99% progress.value = progress.innerHTML = 100; };
progress
eventŅemiet vērā, ka tā vietā,xhr.onprogress
, mēs izmantojamxhr.upload.onprogess
. Kad šis notikums ugunsgrēki, mēs pārbaudām, ka pasākums atbalsta summas aprēķināšanas datu augšupielādēta (thelengthComputable
daļa), un tad aprēķināt pabeigta.
Manā HTML, Es esmu, izmantojot<progress>
elements (līdzīgs<meter>
elements, bet vairāk semantiski piemērots, jo mēs esam uzrādot progresu uzdevuma) rādīt lietotājam, cik daudz no savas fails ir augšupielādēts:
<progress id ="progress" I ="0" max ="100"vērtība ="0">0</progress>
Ņemiet vērā, ka es esmu, izmantojotinnerHTML
pārlūkprogrammām, kas vēl nav atbalstīta<progress>
. Tad ar domuzīmi CSS radīto saturu, ganinnerHTML
unvalue
par progresu var būt vienādi (varbūt vairāk optimizācijas, bet es biju diezgan lepns par sevi tajā laikā!).
Un visbeidzot, Atveidojot Preview#
Kā jauku papildus, we’ll give the user a preview of what we’re uploading for them. It requires theFile API — specifically theFileReader
API.
As the drag-and-drop operation (or theinput[type=file]
) contains a file object, we can hand this over to theFileReader
to get the contents of the file. If it’s something like an image, we can get the Base64 data and give the user a preview. Or if it’s text, we could render it in a<div>
. The MIME type for the file is available as thetype
property on the file object.
So let’s assume we only accept images. Šeit ir preview daļa, kas darbojas pēc faila pārlūkprogramma ir saņēmis:
var acceptedTypes = { 'image/png': true, 'image/jpeg': true, 'image/gif': true }; if (acceptedTypes[file.type] === true) { var reader = new FileReader(); reader.onload = function (event) { var image = new Image(); image.src = event.target.result; image.width = 100; // a fake resize document.body.appendChild(image); }; reader.readAsDataURL(file); }
Mēs izveidotuFileReader
un to failu, lai lasītu. Iepriekš minētajā piemērā, Esmu izmantojisreadAsDataURL
, bet jūs varat arī izlasīt failus teksta un bināro formātu (kā vienu spec).
Kad lasītājs ir lasīt failu un dati ir pieejami, tas ugunsgrēkiload
event, kas, savukārt, rada savu jauno tēlu.
Therezultāts no faila lasīt darbība tiek sniegtaevent.target.result
īpašums. Gadījumā, ja noreadAsDataURL
, vērtība ir pa līnijāmdata:image/png;base64,ABC...
.
Izmantojot visus pieejamos rīkus Šķūnis#
Šis piemērs var būt nedaudz izdomāts par rakstu, ka es gribēju rakstīt. Esmu izmantojis dažādus tehnoloģijas, lai darīt kaut ko, kas ir samērā izplatīta modelis tīmeklī. Patiesībā, tas bija tāpēc, ka man bija problēmas atrast galīgu avots par augšupielādējot uzfaktisks serveris (izņemot, protams, kā es uzrakstīju šo rakstu es atradušis piemērs no muguras vēlu 2010!).
cerams, ka, Jūs redzēsiet, kā katrs mazliet tech var strādāt kopā, lai izveidotu pieteikumu, bet arī es ceru, ka jūs varat redzēt, kur tas strādā, ja nav, vai tikai dažas tehnoloģijas nav pieejams. Pārliecinieties, ka jūs atklāt funkcionalitāti. Pārliecinieties, ka jūs sniedzat atkāpšanās. Pārliecinieties, ka jums izveidot atbildīgi.
Lūk galadrag-and-drop un augšupielādēt demo lai jūs varētu spēlēt ar.