0

I have a question related to the file downloading using POST.

I have the following javascript which sends a POST request to the server side to download a file:

function postCall(url, params) {
    function doPostCall() {
    var newForm = jQuery('<form>', {
        'method':'POST',
        'action': url
    });

    for(key in params) {
        if (params.hasOwnProperty(key)) {
            newForm.append(jQuery('<input>', {
                'name': key,
                'value': params[key],
                'type': 'hidden'
            }));
        }
    }
    newForm.appendTo("body").submit();
}

This method is called from an invisible iframe from the HTML page. This page also has another normal GET request to get a static HTML. However, every time the above method is called, The call to get the static page never returns from the server side.

I know it is a little hard to understand with such little information, but the code are huge and hard to be put here. My question is that:

  1. Is there any obvious problem with the above code which uses an invisible form to send a POST request to get file?
  2. Is there any other better way to send a POST request to the server to download file. (People told that Ajax calls cannot be used to download file)?
  3. If this code is OK and no other way is available. Is there anyway to force this method to be run at the last thing after the whole page is loaded and all other requests are completed?
Hugo Dozois
  • 8,147
  • 12
  • 54
  • 58
Kevin
  • 5,972
  • 17
  • 63
  • 87
  • Does the get request get aborted due to a page reload initiated by the form post? usually a form post like this has a target attribute pointing at a specific iframe, resulting in the iframe reloading but not the entire page, which would allow your get request to complete. – Kevin B Aug 02 '13 at 15:14
  • I don't see why you could not use AJAX to do a download. And why use a POST when you are GETting something? – putvande Aug 02 '13 at 15:15
  • @putvande because using ajax, you can't send the content as a file to the user's computer. – Kevin B Aug 02 '13 at 15:15
  • @KevinB but you could do a window.location.href in the callback for this file which downloads the file. – putvande Aug 02 '13 at 15:18
  • "Is there anyway to force this method to be run at the last thing after the whole page is loaded and all other requests are completed?" -- Yes, [`.ajaxComplete()`](http://api.jquery.com/ajaxComplete/) – Blazemonger Aug 02 '13 at 15:18
  • What's unclear here is the exact location of the form. If the form is indeed inside of said invisible iframe, then the get request on the parent page should not be affected. *"This method is called **from** an invisible iframe **from** the HTML page."* is very unclear. Is it *from* the iframe or *from* the parent page. can't be both. – Kevin B Aug 02 '13 at 15:18
  • @putvande yes, but then you wouldn't be downloading a file with ajax. at most the ajax would be telling the server to generate the file. – Kevin B Aug 02 '13 at 15:20
  • You might get any help with this article? http://stackoverflow.com/questions/7924157/jquery-how-to-submit-a-post-multipart-form-data-from-a-form-and-get-your-f?rq=1 – tchoum Aug 02 '13 at 15:24
  • The server does not generate any static URL for file downloading. It is a Java servlet and simply write the binary into the stream. I think the window.location.href won't work. am I right? – Kevin Aug 02 '13 at 15:33

1 Answers1

0
  1. It's not very clear from the description in the GET request is sent from the same iframe or not. It yes, then after submitting the form the iframe content reloads - because it's not an AJAX request - stopping all other javascript code that runs in the iframe.

  2. Well, you can add 'target="_blank"' attribute to the form - in this case the iframe content won't reload on form submit.

  3. Yes, it's quite possible. jQuery.ajax method returns the Deferred object. So you can store those deferred objects in an array variable and wait until all the deferred have been resolved. And run the POST submit only then. jquery.whenAll plugin can simplify this task:

    jQuery.whenAll(
      $.get( URL1 ),
      $.get( URL2 )
    )
    .always(function(results) { postCall(url, params) });
    
amakhrov
  • 3,820
  • 1
  • 13
  • 12