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>
Get our Articles via Email. Enter your email address.

You may also like...

76 Comments

  1. Usman says:

    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 ?

  2. Marakas says:

    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.

  3. GOPalmer says:

    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

  4. beAuty hanyA says:

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

  5. steve kleiman says:

    This is awesome. Works great. Thank you!

  6. Nags says:

    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

  7. Fantab says:

    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

  8. gndlgisdbna says:

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

  9. gndlgisdbna says:

    Hats off! It totally worked. Thanks!

  10. Franc says:

    Pls place some demo works..

  11. Anji says:

    Thanks Just i want know execute this program in JSP

  12. Abhishek Sikka says:

    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!!

  13. ranjit says:

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

  14. Foo Bar says:

    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…”);
    }

  15. 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

  16. Thanks for sharing… It totally worked… Thanks..

  17. nikhil says:

    thanks for the nice solution

  18. yui says:

    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.

  19. Deepak says:

    Thanks….

  20. Jason Russo says:

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

  21. Lakshmeepathi G says:

    window.frames[‘upload_iframe’].name = “upload_iframe”;

    The above line when excluded in FF,it works excellent.
    But when excluded in IE,instead of the file sitting in the iframe,a separate window opens.
    What is the purpose of the above line? ( because we have already set the ‘name’ attribute for iframe in setAttribute() method ) ( to confirm if the name attribute was set,I printed in alert(iframe.name) and that worked fine too )
    If setAtrribute is a problem in IE,can you please provide the reason for it and the solution for ir?

  22. Arvind says:

    nice post

    thanks….

  23. Corpus says:

    Thanks. Nice script..
    But I have some issue what am not able to upload more then 20KB.
    Please. any one help me ..?

    • Vijay Kanta says:

      Maximum allowed sizes for file uploads are generally in the server settings. If you are using PHP for server side scripting, change the max allowed size in your .ini file. If you’re using shared hosting, you’re out of luck.

  24. Reza Baiat says:

    Hi
    NEVER FORGET to assign name to your file upload input. It took 40 days of my time!!!

  25. Vijay Kanta says:

    Worked like a treat! Kudos to you!

  26. Max says:

    Does it work in cross domain also????????????

  27. Khai says:

    Thanks, nice works…

    Here is server side example. Do not name it index.php. Name it something like “upload_process.php”.
    This example shows uploaded file info. and text content.

     0)
      {
      echo "Error: " . $_FILES["datafile"]["error"] . "";
      }
    else
      {
      echo "Upload: " . $_FILES["datafile"]["name"] . "";
      echo "path: " . $_FILES["datafile"]["dir"] . "";
      echo "Type: " . $_FILES["datafile"]["type"] . "";
      echo "Size: " . ($_FILES["datafile"]["size"] / 1024) . " Kb";
      echo "Stored in: " . $_FILES["datafile"]["tmp_name"] . "";
    }
      $tempfile = $_FILES["datafile"]["tmp_name"];
      $fp = @fopen($tempfile, "r");
      if ($fp)
      {
        while(!feof($fp))
        {
          $i++;
          $lin  = fgets($fp);
          $lin  = str_replace("\r\n","",$lin);
          echo $lin;
        }
        fclose($fp);
      }
    ?>;
    
  28. maxwebster says:

    Thanks, I have lots and lots of IE users ARRRGGG – this works like a charm!

  29. Dude says:
    form.parentNode.appendChild(iframe);
    window.frames['upload_iframe'].name = "upload_iframe";
    iframeId = document.getElementById("upload_iframe");

    Aren’t the last 2 lines unnecessary? You are setting the iframe’s name in the beginning using iframe.setAttribute(“name”, “upload_iframe”); And why are you getting the iframe by calling document.getElementById? You have it’s link in ‘iframe’ variable already :)

  30. sid says:

    can I use the same in Struts also.

  31. NIshith says:

    Can you please give me jsp file upload server script instead of php and also tell me that how to set response in jsp and how to receive in html

  32. anonymous says:

    I try to convert this code to jquery is there anyone that can help me?

    • anonymous says:

      Sorry, you have the answer in the comment of Foo Bar it works great in IE/Mozilla/Google Chrome

    • anonymous says:

      Sorry, you have the answer in the comment of Foo Bar it works great in IE/Mozilla/Google Chrome

  33. Krishna says:

    Excellent boss you saved me

  34. Amit SHarma says:

    Hi i used the above script and it works very well in mozilla but not working at all in IE.
    I am getting Access denied error on form.submit().
    Below is jsfiddle link resembling my implementation
    http://jsfiddle.net/URkbL/1/

    Please help..

  35. Ameenulla says:

    after uploading file. when i submit form it is opening new window in chrome. please help

  36. RangaReddy Julakanti says:

    working very nice sir,i can’t forget

  37. Raj says:

    Hi,
    I have an issue, will be very thankful if anyone clarifies it. Am using struts 1.4.
    In my screen I have a 1000 rows of records, now i want to submit this page to save 1000 records, so I formed an xml content and through ajax submit I tried to submit, before submit in alert values are displayed but after ajax submit all my form elements are null in my action class. Is there any size limit for ajax submit and my form method is POST.

    Thanks,
    Raj

  38. Peyman says:

    Hi, thank you…

  39. Kendor says:

    Hi, thanks for sharing
    a good solution
    but, i have problem when i put form upload file in other form
    so when finish upload file, action other form be change too
    Ex:

    <form method="post" name="primaryForm" action="regis.php">
    <form>
    <input type="file" name="datafile" /></br>
    <input type="button" value="upload"
            onClick="fileUpload(this.form,'upload.php','upload'); return false;" >
    <div id="upload"></div>
    </form>
    </form>
    

    after upload, primaryForm be change action to upload.php :(
    i want to primaryForm action to regis.php
    Please give a solution!

    • win naung says:

      Hi Kendor,

      Could you solve your issue? I encountered the issue like you.

      I don’t know how to solve this issue.

      If you got any idea, please share to me.

      Thanks
      Win

      • kendor says:

        Hi win naung,
        I try more other solutions but not can solve it
        so that i split other step
        example:
        step1->input email, name
        step2->upload images
        step3->confirm
        step4->complete
        ^_^

  40. Somnath says:

    When I select a file it gives a permission denied in the following line of code:
    // Message from server…
    if (iframeId.contentDocument) {

    but if i simply click on upload button with out selecting any file it works fine. Sure it is something related to permission issue. I am using Window 7 and VS 2010.

    Also it will be very helpfull if someone can share the C# code for the server side as well. I am using ASP.NEt WEB API.

    Thanks
    Somnath

    • Somnath says:

      Please ignore my previous query… I found the issue…. Please share me the server side code in C#. I am using MVC 4 WEB API.

      Thanks
      Somnath

  41. ahmed says:

    man that was so smart

  42. sree says:

    final MfTextArea question = new MfTextArea(“question”, new Model(“Your Question”),
    new PropertyModel(getItem(), “question”), QUESTION_MAX_LENGTH, true);
    question.setCharactersLeftJS(QUESTION_MAX_LENGTH);
    question.setRows(10);
    question.setCols(50);
    question.setMfRendering(false);
    form.add(new MfTablelessFieldLayoutBorder(“questionWrapper”, question));

    MfFileUploadPanel fileUpload =
    new MfFileUploadPanel(“fileUpload”, “Attachments”,
    new PropertyModel<List>(getItem(),
    “attachments”), false, “”);
    fileUpload.setMaxFiles(5);

    MfFileContentTypeValidator fileContentTypeValidator = new MfFileContentTypeValidator(
    Arrays.asList(allowedAttachments));
    fileUpload.addValidator(fileContentTypeValidator);

    fileUpload.setVisible(getItem().isAttachmentsAllowed());
    fileUpload.setNamingStrategy(getItem().getFileUploadNamingStrategy());
    fileUpload.setOutputMarkupPlaceholderTag(true);
    fileUpload.setMfRendering(false);
    form.add(new MfTablelessFieldLayoutBorder(“fileUploadWrapper”, fileUpload));

    buttons = new MfButtonPanel(“submit”, “Continue”);
    buttons.setOutputMarkupId(true);

    buttonWrapper = new MfTablelessFieldLayoutBorder(“submitWrapper”, buttons);
    buttonWrapper.setOutputMarkupId(true);
    form.add(buttonWrapper);
    questionDiv.add(form);

    Multiple attachments/Browse buttons getting displayed on askanewquestion page for ie8… what could be the reason?? any help appreciated.

    thanks

  43. Epiphany says:

    I’m sorry Viral, but you will need to update this article, as file uploads using ajax ARE possible now in almost all browsers supporting HTML5 with the XMLHttpRequest2 ‘FormData’ form object.

    Start here first for more info…
    https://developer.mozilla.org/en-US/docs/Web/API/FormData

    Then bop over to StackOverflow for a multitude of questions and answers on using the formdata object in HTML5 to upload files with ajax.

    Important that programmers stay up to date, and even though the formdata api in HTML5 is still not officially ratified, all major browsers, including mobile browsers, support it already (I believe at this point in time, only Safari Mini mobile browser is the ONLY one that does not).

    With HTML5 and the FormData object, we can now even upload binary data as blobs as well with AJAX. There are even many plugins for this at this point in both vanilla javascript and jquery flavors.

    I know this post is older, but felt it necessary to mention this based on the very recent dates on other comments, where the posters are not aware your claim at the head of this article are no longer the case. Uploading binary data (files) with ajax is alive and well, and in heavy use already.

  44. Epiphany says:

    Sorry… One more thing… Gmail has been using flash for their Gmail since 2012, just to let you know!

    • Sandman says:

      GMAIL uses Flash to send files because of checking file size before it is sent.
      There is no other way (in my knowledge) to check file size or any other params before it is sent to serwer side :)

  45. Steed says:

    I was lost. FOR 9 days. you sir are my saviour.

    iframeId.parentNode.removeChild giving me issues though?

  46. shads says:

    how can I display the uploaded files in a div on the same page

  47. Sudhakar says:

    Thanks Patel! Works Perfectly! You Save My DAY :) Thank you SOMUCH.

  48. Nice Viral Patel its is perfect example of file uploading process without refreashing page. I want to say thanks from core of my heart. Its amazing. WoW :-)

  49. Hamouda says:

    Thanks…

  50. nidhi says:

    very helpfull post

  51. Ajay says:

    Hi,
    I found this post really helpful.But I am facing some issues in here.After file upload the message inside the is not getting cleared.Also the the filename selected earlier is also not getting cleared when we click for a new upload.

  52. Nibu says:

    Thanks for the tutorial. I tried the above solution in IE8 and it is throwing “Access is denied” error

  53. Ambika says:

    Amazing, it works :). Thanks

  54. Shantanu says:

    Awesome solution, It worked for me. I faught a lot to achieve file upload functionality in modal dialog and finally got this solution.Thanks Very Much.

  55. Anurag says:

    Thnks But How to create scripted server to recieve uploads….??

  56. crzhacko says:

    What’s the difference between ‘iframe’ and ‘iframeId’ variables? I guess they are same.

  57. Walid says:

    It worked very well for me !! Thank you very much :D

  58. Umair Hamid says:

    You are just great man, Tell me how can I cad image path in it. I am already echo in php

  59. SMan says:

    Amazing, works as-is!! Great!!!

  60. Nelson Rakson says:

    Nice work but you made it more complicated! It could be simplified a lot

    • rocbar says:

      Nelson – Can you provide a working version of a simplified script?

  61. Shekhar says:

    Hi Viral

    Thanks for uploading this post.
    really very helpful

    I have integrated the code u provided but on IE8 it is returning a download pop up which contains json response which currenly we are printing on page.

    is there any workaround to prevent this pop up.

  62. Murthy says:

    What is the Controller logic?
    Can I use like this?
    @RequestMapping(value={“index.php”}, method=RequestMethod.POST)
    public @ResponseBody boolean optInFileUpload(CommonsMultipartFile file){…. }

  63. Don says:

    This is brilliant, and it beats the heck out of AJAX. Thank you kind sir !!!

  64. Cazz says:

    Is there a way to get a response back using this method ?

  65. Sunil Kumar says:

    Hey Thanks,
    Nice article. I was searching from many hours to find the solution provided here.
    Thanks

  66. Roshan says:

    How does the data from the server side retrieves to above mention page after the form is submitted.
    I am rendering some json data
    Suppose {a:1,b:12,c:13}. How to show these data in readable form.

  67. Fragata says:

    Finally! Thaaaaaank you very much, it was what I wanted, and surprisingly without ajax.

Leave a Reply

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