HTML5 and Javascript: file upload with progress bar, client-side image resizing and multiple runtimes
Dec 13, 2015
There are tons of libraries on the web, such as shown in this list, but these libraries are always much more complicated than needed, and modifying them will require 10 times more work than do it from scratch.
So let us see the different components to do our own file uploader script.
Which request ?
For files, it’s necessarily a POST request (passing the file in the parameters of a GET request would be possible for small files though but a very bad anti-pattern).
There exists different encoding format for the content of the data :
application/x-www-form-urlencoded
text/plain
multipart/form-data
The multipart/form-data type is the recommended one for files since you can upload multiple files and chunks of files.
In the form tag element <form>, the format is usually specified by the enctype attribute and the correct request is made by the browser on input change. Default is application/x-www-form-urlencoded.
The XMLHttpRequest Object and the progress status
XMLHttpRequest enables to send a HTTP Request to server in Javascript and is used heavily in AJAX programming.
Another way to write it for GET requests is using xhr.addEventListener("progress", updateProgress); xhr.addEventListener("load", transferComplete); xhr.addEventListener("error", transferFailed); xhr.addEventListener("abort", transferCanceled).
For POST requests, you need to monitor also the upload progress with :
I would advise the use of a HTML <progress> element to display current progress.
Using jQuery
The FormData Element
The FormData element simplifies the creation of a POST request of type multipart/form-data (demonstration here) and the call to send a form is simply :
It uses the XMLHttpRequest method send() to send the form’s data.
Let’s use PutsReq service that is a free file bin to debug our POST requests and send it a file :
The field “webmasterfile” is a Blob. A Blob object represents a file-like object of immutable, raw data.
The File interface is based on Blob, inheriting blob functionality and expanding it to support files on the user’s system.
Resize image size client-side with FileReader API
Taken from here, here is a full upload with a resize :
You can also add drag-and-drop functionality very easily following this tutorial.
Lastly, you can also, during a drag-and-drop of an image from another browser window, get the URL of the image to send to the server :
var url = event.dataTransfer.getData('URL');
Read EXIF information
If the picture is taken from a mobile camera, then we need to correct the orientation of the data to get it the right way. This can be done with the exif library