AJAX Uploading with HTML5′s File API
Prior to HTML5 and its File API, getting media from a user was a somewhat sordid affair. You generally either had a static page with an <input> element of a <form> posting to a processing file or utilized some third party script that relied on a Flash bridge or <iframe> shenanigans to asynchronously get the file where it needed to go.
This leads to things like this demo and how you can drag ‘n drop (‘n upload) files with Gmail. Seeing as how I was tired of doing the aforementioned Flash or <iframe> bullhonky, I decided it was time to get the ball rolling for myself.
Accessing the Files
It’s actually surprisingly simple to see what a user has chosen to upload in a <input> (of a file type, of course). You can access all of the vital pieces of information through JavaScript once they’ve been selected, and I say “they” because if you specify the multiple attribute in the <input>, you can then select multiple items:
1 2 3 4 5 6 7 8 9 | document.getElementById('file-input-element').onchange = function(){ if(this.files.length < 1) return false; for(var i = 0; i < this.files.length; i++) console.log(this.files[i]); }; /** * name - file name * size - file size in bytes * type - file MIME type **/ |
Aside from the attributes, there are also some pretty sweet functions like getAsDataURL() and getAsText() which can have some cool uses (such as dynamically loading an image as a CSS background image in data form), but we’ll have to save that for another day. All we need right now is access to that files array.
Uploading the Files
It starts pretty much the same as any other AJAX data transfer, which is with a XMLHttpRequest object. The only difference is that since usually everything I do is with a GET request, I just put any key-value pairs in the URL and access the information server side. However, since the file data may (and probably will) exceed the URI size limit, it’s best to go with POST.
So then you may be asking “how do we get the files to go along with the XHR request?” It’s actually quite simple: just use a FormData object.
1 2 3 4 5 6 7 8 9 10 11 12 | var xhr = new XMLHttpRequest(); xhr.upload.addEventListener('progress',function(ev){ console.log((ev.loaded/ev.total)+'%'); }, false); xhr.onreadystatechange = function(ev){ // Blah blah blah, you know how to make AJAX requests }; xhr.open('POST', url, true); var files = document.getElementById('file-input-element').files; var data = new FormData(); for(var i = 0; i < files.length; i++) data.append('file'+i, files[i]); xhr.send(data); |
You might be wondering why not just use the FileReader interface and upload with something pre-built like the jQuery $.ajax() method, and you’ll find the answer in the progress event listener; the $.ajax() method and the like doesn’t allow for it and I really want to display an upload progress bar, dammit!
Is that it?
Yeah, that’s it. Pretty easy, right? On the server side, the files are accessed just as if they were uploaded via a form and POSTed (in PHP’s case, they’re located all in the $_FILES array). I bundled it all up in a nice little JavaScript object which you can find over at my GitHub complete with options and some helpful methods. Have fun with it and be sure to leave a comment if you think of something I could/should change.
View the demo (requires an HTML5-capable browser). I hacked together my own version of a <progress> element since at the time of this writing, only WebKit browsers have it sufficiently implemented (though I can’t seem to figure out why it doesn’t fully function as expected in Opera).
[...] 9. Ajax Uploading With HTML5 File api [...]
[...] 9- Ajax Uploading With HTML5 File api [...]
Microsoft JScript runtime error: ‘this.xhr.upload’ is null or not an object————
show this error in IE and not working FF and chrome
pls help me
It doesn’t work, it just sends xhr request, but not the file. You need to read the file in order to send it as a binary data
I do read the file. Each file (or just a file) is added to the FormData object and then sent. It most definitely works; I currently use it in multiple projects. What browser are you using?
How to I make the code on your gethub work?
It looks like it’s working. Larger files take longer to get to 100%. But, I don’t see any files on the server. I’ve tried setting the dir perms to 777. Is there something I need to change besides just copying your files to my website? I have them in a nested folder if that matters.
You’re going to need more than just the JavaScript and HTML file from my GitHub. The file you upload is not dumped straight to whatever location you want; you still need to process it server-side. For instance, in PHP, your code would need to do something like this:
Hope that helps!
I can’t get this to work – my PHP file does not see any files or POSTed form fields. The only difference I can see from the Chrome developer tool – network page is that your “content-type” is multipart/form-data with xxxxx added, whereas mine just shows the multipart/form-data. I don’t see in your uploader.js file where you set the content type (I am setting manually based on whether or not there is a file to upload – it’s just application/x-www-form-urlencoded when there is no file. Thanks!
You shouldn’t have to set the content type. And what do you mean “xxxxx added?” This would be a lot easier if you posted some of your code or had a screenshot or something.
[...] 9. AJAX UPLOADING WITH HTML5 FILE API [...]
Useful information. Lucky me I discovered your website unintentionally, and I am stunned why this coincidence did not came about earlier! I bookmarked it.
Thanks!
Dude, you are extremly awesome, I can’t tell you how much you’ve helped me. Thanks a lot, I’ve seen other “tutorials” (yeah sure) and this explains and simplifies it perfectly. Hope you keep up the good work.
[...] 9. Ajax Uploading With HTML5 File api [...]
CSS is designed primarily to enable the separation of document content (written in HTML or a similar markup language) from document presentation, including elements such as the layout, colors, and fonts.This separation can improve content accessibility, provide more flexibility and control in the specification of presentation characteristics, enable multiple pages to share formatting, and reduce complexity and repetition in the structural content (such as by allowing for tableless web design). “^
Most recent posting coming from our web portal
<http://www.caramoan.co
Hello, Upload failed on Windows platform.
Do I need to add anything to the file’s code?!
I see you share interesting content here, you can earn some extra money, your website has big potential, for
the monetizing method, just type in google – K2 advices how
to monetize a website
I thought I’d have to read a book for a diseovcry like this!
Nice article. Found this tool to validate JavaScript. http://codebeautify.org/jsviewer
[…] possibile utilizzare ajax con file html5 api. Vedi questo post Dare un’occhiata al mio accettato di rispondere : […]
I couldn’t refrain from commenting. Perfectly written!