I hope everyone knows what AJAX is. For those who don’t, I have to disappoint You, this article will not give You any useful information. This article is about method which will help developers make forms which upload files to web servers asynchronously (without leaving/reloading current web page).
What is AJAX and can You upload files using it?
AJAX is Asynchronous JavaScript And XML. As we know XML is meant to store structured data. In most cases its text data, but what about binary data, in this case files? Can we use AJAX to transfer/upload files to web server?
Well the answer is NO. You can’t upload files using AJAX, but You can do it with a bit of a modification, maybe lets call it some kind of adaptation of another technology.
The heart of AJAX technology is the XMLHttpRequest concept which was originally developed by Microsoft. It was built in into the Internet Explorer, and later into all other major browsers. Here is the simple function that utilizes the XMLHttpRequest:
function ajax(url, params, callbackFunction){ var request = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP.3.0"); request.open("POST", url, true); request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); request.onreadystatechange = function() { if (request.readyState == 4 && request.status == 200) { if (request.responseText){ callbackFunction(request.responseText); } } }; request.send(params); }
The good thing about XMLHttpRequest is that you can retrieve XML/HTML or other documents without leaving the current page and with that you can specify any number of parameters (like HTML form fields). The bad thing? Oh yes NO FILES as parameters, so it means that You can’t upload files!
How to upload files asynchronously?
As I described above You can’t upload files using AJAX. Some time ago I wrote a JavaScript file upload object which as You already understood can help developers make forms which upload files asynchronously.
Today I made some modifications to this code and I want You to try it. Its simple, really fast to implement. Just paste this code into your document or external JavaScript (ajaxupload.js) file:
// AsyncUpload v1.2 // // Changelog: // v1.2 code was updated after chamnap'a comment. // v1.1 full code rewrite. // v1.0 initial code. AsyncUpload = { createFrame : function(formElement, completeCallback) { var frameName = 'f' + Math.floor(Math.random() * 99999); var divElement = document.createElement('DIV'); divElement.innerHTML = '<iframe style="display:none" src="about:blank" id="'+frameName+'" name="'+frameName+'" onload="AsyncUpload.documentLoaded(\''+frameName+'\')"></iframe>'; document.body.appendChild(divElement); var frameElement = document.getElementById(frameName); if (completeCallback && typeof(completeCallback) == 'function') { frameElement.completeCallback = completeCallback; } formElement.setAttribute('target', frameName); }, documentLoaded : function(elementID) { var frameElement = document.getElementById(elementID); if (frameElement.contentDocument) { var documentElement = frameElement.contentDocument; } else if (frameElement.contentWindow) { var documentElement = frameElement.contentWindow.document; } else { var documentElement = window.frames[elementID].document; } if (documentElement.location.href == "about:blank") { return; } var result = documentElement.body.innerHTML; if (!document.all) { frameElement.setAttribute("src", "about:blank"); document.body.removeChild(frameElement.parentNode); } else { document.body.removeChild(frameElement.parentElement); } if (typeof(frameElement.completeCallback) == 'function') { frameElement.completeCallback(result); } }, submitForm : function(formElement, startCallback, completeCallback) { AsyncUpload.createFrame(formElement, completeCallback); if (startCallback && typeof(startCallback) == 'function') { return startCallback(); } else { return true; } } }
Now write your xHTML document (index.html). Let say it will look like this:
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Asynchronous Upload</title> <script type="text/javascript" src="ajaxupload.js"></script> <script type="text/javascript"> function startCallback() { return true; } function completeCallback(response) { obj = eval('('+response+')'); alert(obj.firstname); document.getElementById('r').innerHTML = response; } </script> </head> <body> <form action="index.php" method="post" enctype="multipart/form-data" onsubmit="return AsyncUpload.submitForm(this, startCallback, completeCallback)"> <div><label>First name:</label> <input type="text" name="firstname" /></div> <div><label>Last name:</label> <input type="text" name="lastname" /></div> <div><label>CV:</label> <input type="file" name="cv" /></div> <div><input type="submit" value="SUBMIT" /></div> </form> <p>Response: <span id="r"></span></p> </body> </html>
On backend (web server) i wrote this PHP script (index.php):
< ?php echo json_encode( array_merge( $_REQUEST, $_FILES ) ); ?>
Now You must fill the form (firstname, lastname and attach CV file) to test it. When You submit the form, the current page won’t reload. This script will load the index.php file in the background (CV file will be sent in the background too). PHP script will output JSON (about this technology maybe some other time) encoded string.
In the index.html file function completeCallback will handle the index.php response without reloading the page. Voila! Now You only need to figure it out where You can use this JavaScript Asynchronous File Upload Object.
Download the example
I have made a .zip package containing all the above scripts. Just drop them into Your web server and point Your browser to index.html file to test it.
















