As a part of HTML5, XMLHttpRequest API is undergoing enhancements. You can now upload files to a server and display a progress bar. Files are uploaded in their raw source format. That is not same as uploading a file using the old <input type="file"/> approach.
The basic steps are as follows:
- Use the HTML5 File API to let the user select a list of files or drag and drop files on an element.
- Upload these files using XMLHttpRequest Level 2.
Setting Up a Basic UI
Here is a very simple UI for dropping files and uploading them.
<div id="fileDrop"> <p>Drop files here</p> </div> <a id="upload" href="#">Upload files</a>
You can style it better in real life. We will just show the basic code here.
Setting up File Drag and Drop
Within a <script> element, add these lines.
var files; //Stop default actions function stopProp(ev) { ev.stopPropagation(); ev.preventDefault(); } function init() { var dropZone = document.getElementById("fileDrop"); //dropZone.addEventListener("dragenter", stopProp, false); //dropZone.addEventListener("dragleave", stopProp, false); dropZone.addEventListener("dragover", stopProp, false); dropZone.addEventListener("drop", setFile, false); var upload = document.getElementById("upload"); upload.addEventListener("click", doUpload, false); } //Save the dropped files function setFile(e) { e.stopPropagation(); e.preventDefault(); files = e.dataTransfer.files; alert(files.name); return false; } window.onload = init; function doUpload(e) { //Upload code here }
Basically, when files are dropped, we save them in the files global variable. Also, we set the onclick handler of the Upload link to the doUpload() method.
Upload Files
To keep things simple in this article, we will upload only one of the dropped files. You can easily change the code to upload all files.
Fill out the doUpload() method as follows.
function doUpload(e) { var xhr = new XMLHttpRequest(); var file = files; xhr.open("POST", "upload.jsp"); //Set a few headers so we know the file name in the server xhr.setRequestHeader("Cache-Control", "no-cache"); xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); xhr.setRequestHeader("X-File-Name", file.name); //Initiate upload xhr.send(file); stopProp(e); }
The Server Side
The browser sends the contents of the file in the request body. A typical request will look like this.
POST /UploadTest/upload.jsp HTTP/1.1 Host: localhost:8080 Connection: keep-alive Content-Length: 48 Origin: http://localhost:8266 X-Requested-With: XMLHttpRequest Cache-Control: no-cache X-File-Name: Story.txt User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7 Accept: */* Referer: http://localhost:8266/UploadTest/index.html Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 Cookie: JSESSIONID=0CDE28BDE75AD2B9486070FDA5AED6DB Long long ago.... In a galaxy far far away...
If the file is binary, all the bytes will be sent in raw form without any kind of base 64 encoding.
To read this type of data, you will need to get the input stream of the request. In a Servlet or JSP, this can be done by calling ServletInputStream getInputStream() method of HttpServletRequest object. Using the input stream, you can read all the data.