Ajax Style File Uploading using Hidden iFrame

File uploading using AJAX is not possible. AJAX doesn’t actually post forms to the server, it sends selected data to the server in the form of a POST or GET request. As javascript is not capable of grabbing the file from the users machine and sending it to the server, it’s just not possible with AJAX. You have to resort to regular old form submit.

If you have read/seen it somewhere, then it is not through AJAX. File uploading occurs through an iframe in this case. You have to use a iframe to upload the files. So, you can use iframe to asynchronous upload (Like AJAX , but its not AJAX).

How file uploading is done in Gmail? Use following JavaScript function, if you want to achieve same functionality.

<html>

<script language="Javascript">
function fileUpload(form, action_url, div_id) {
    // Create the iframe...
    var iframe = document.createElement("iframe");
    iframe.setAttribute("id", "upload_iframe");
    iframe.setAttribute("name", "upload_iframe");
    iframe.setAttribute("width", "0");
    iframe.setAttribute("height", "0");
    iframe.setAttribute("border", "0");
    iframe.setAttribute("style", "width: 0; height: 0; border: none;");

    // Add to document...
    form.parentNode.appendChild(iframe);
    window.frames['upload_iframe'].name = "upload_iframe";

    iframeId = document.getElementById("upload_iframe");

    // Add event...
    var eventHandler = function () {

            if (iframeId.detachEvent) iframeId.detachEvent("onload", eventHandler);
            else iframeId.removeEventListener("load", eventHandler, false);

            // Message from server...
            if (iframeId.contentDocument) {
                content = iframeId.contentDocument.body.innerHTML;
            } else if (iframeId.contentWindow) {
                content = iframeId.contentWindow.document.body.innerHTML;
            } else if (iframeId.document) {
                content = iframeId.document.body.innerHTML;
            }

            document.getElementById(div_id).innerHTML = content;

            // Del the iframe...
            setTimeout('iframeId.parentNode.removeChild(iframeId)', 250);
        }

    if (iframeId.addEventListener) iframeId.addEventListener("load", eventHandler, true);
    if (iframeId.attachEvent) iframeId.attachEvent("onload", eventHandler);

    // Set properties of form...
    form.setAttribute("target", "upload_iframe");
    form.setAttribute("action", action_url);
    form.setAttribute("method", "post");
    form.setAttribute("enctype", "multipart/form-data");
    form.setAttribute("encoding", "multipart/form-data");

    // Submit the form...
    form.submit();

    document.getElementById(div_id).innerHTML = "Uploading...";
}
</script>

<!-- index.php could be any script server-side for receive uploads. -->
<form>
<input type="file" name="datafile" /></br>
<input type="button" value="upload"
        onClick="fileUpload(this.form,'index.php','upload'); return false;" >
<div id="upload"></div>
</form>

</html>


21 Comments

  • Usman wrote on 5 March, 2009, 5:54

    Hi! Thanks for such a nice tip, although data seem posted but one problem is that IFrame start downlaoding in IE what could be the issue is ?

  • Marakas wrote on 24 March, 2009, 11:10

    Thanks for sharing! I used your code as a base and mixed in some jquery methods for the binding and it worked perfectly on ie and firefox.

  • GOPalmer wrote on 24 April, 2009, 23:35

    You should add the var keyword to lines 31,33,35 before the content variable as IE7 throws an error. Very useful script though.

    George

  • beAuty hanyA wrote on 26 May, 2009, 15:06

    hm, can you show an example of a server-side script for receiving the upload.

  • steve kleiman wrote on 19 August, 2009, 23:39

    This is awesome. Works great. Thank you!

  • Nags wrote on 29 December, 2009, 9:13

    I am unable to implement the server side script. In the server side script i gave my action class name but it throws an error. Can you please give me some example of how to implement the server side scripting

  • Fantab wrote on 6 January, 2010, 5:36

    Very nice and easy to understand code. Thanks for sharing.

    What should I do if I want to know when the uploading is done (e.g. to display new content to users) or to display a file-size-over-limit message to users?

    Many thanks,

    Fantab

  • gndlgisdbna wrote on 17 November, 2010, 4:07

    Very interesting script. I am going to try it right now and will let you know how it goes.

  • gndlgisdbna wrote on 17 November, 2010, 10:47

    Hats off! It totally worked. Thanks!

  • Franc wrote on 24 May, 2011, 16:54

    Pls place some demo works..

  • Anji wrote on 4 June, 2011, 0:11

    Thanks Just i want know execute this program in JSP

  • Abhishek Sikka wrote on 6 June, 2011, 17:06

    It’s been 1 hour since I read this and here I am gloating to my colleagues that i did what no one could do even after a weeks effort .. Awesome article .. Cheers!!

  • ranjit wrote on 7 September, 2011, 16:04

    Please Anybody can tell me how to receive image at server side with example .

  • Foo Bar wrote on 30 October, 2011, 23:21

    Hey if you want to use jQuery, I ported (not tested):

    function asyncFormSubmit(form, resultDiv) {

    // Create the iframe…
    var iframe = $(”);
    $(‘body’).append(iframe);
    iframe.attr(‘name’, ‘upload_iframe’);
    iframe.attr(‘id’, ‘upload_iframe’);
    iframe.hide();

    // When iframe loads, copy content back to target
    function copyIframe () {
    var content = $(iframe).contents().find(‘body’).html();
    $(resultDiv).html(content);
    setTimeout(function () { $(iframe).remove(); }, 250);
    }
    $(iframe).one(‘load’, copyIframe);

    // Set properties of form…
    $(form).attr(“target”,”upload_iframe”);

    // Submit the form. This triggers the iframe to “load” the
    // response from the server. Once loaded we can then do other
    // stuff.
    $(form).submit();

    // This gets replaced by iframe content when ready
    $(resultDiv).html(“Uploading…”);
    }

  • Archan Ghosal wrote on 6 December, 2011, 19:03

    I design a more simplified ajax style file upload page without using JavaScript. I place a hidden iFrame just before the form tag. Please read the following.
    http://ramui.com/articles/ajax-file-upload-using-iframe.html

  • J-Tech Solutions wrote on 8 January, 2012, 1:14

    Thanks for sharing… It totally worked… Thanks..

  • nikhil wrote on 10 January, 2012, 17:57

    thanks for the nice solution

  • yui wrote on 14 January, 2012, 4:35

    just i want to know if can change the content-type for the uploaded file and if i can set or change request headers thanks.

  • Deepak wrote on 16 January, 2012, 17:43

    Thanks….

  • Jason Russo wrote on 10 May, 2012, 3:10

    Thanks. Nice script. Worked perfectly on my first try.. Also, thanks foo bar for the jQuery snippet.. cheers!

Leave a Reply

Your email address will not be published. Required fields are marked *

*