0

I'm attempting to return an Excel file through a Ajax POST to the server, the server generates the .xls file, however it doesn't pass through to the front end, i think it has something to do with how i'm handling the response.

It should kick off a file download of the Excel file. Originally i had dataType JSON, but after searching through threads i figure it's something to do with the dataType format and the .done function, but cannot work out what it should be.

function requestFile(myJSON) {
    var urlrequest = "mywebappexport/excel";
    var link = $('#exportbtn');
    $.ajax({
        url: link.attr('href'),
        type: "POST",
        data: JSON.stringify(myJSON),
        cache: true,
        contentType: "application/json; charset=utf-8",
        complete: function (data) {
        var ifr = ($('<iframe />').attr('src',     link.attr('href')).hide().appendTo(link))
        setTimeout(function () {ifr.remove();}, 5000);
    }
    })

};

Updated code: working on modern browsers but fails on IE8 - with the error Unexpected call to method or property access. In jQuery version 1.9.1.js. this.appendChild( elem );

Hagbard
  • 575
  • 5
  • 8
  • 18

2 Answers2

3

You cannot use AJAX to download files from the server. The browser will deny Javascript from accessing the user's filesystem.

You should look at providing a "download servlet" on your server side, which can set the appropriate headers to ensure the browser downloads the file or prompts the user to save a stream it is receiving from the Server.

As noted here, you could also certain plugins that can provide you an AJAX-like experience. Internally they might be using iFrames to simulate AJAX-like behavior.

Community
  • 1
  • 1
Serendipity
  • 1,015
  • 1
  • 10
  • 19
  • Thanks for the answer, the server is set up to do that as far as i'm aware, i'm using postman to debug and i get the excel file generated as text in there, it's just triggering it through the AJAX that i think i'm having issues with. I've tried adding dataType: application/vnd.ms-excel" but no help – Hagbard May 06 '14 at 14:43
  • @Hagbard AJAX will not work. You should look at alternatives. Postman (from what I've read in two minutes) seems like an extension on Chrome to help test RESTful services. That is not the same as using Javascript to download a file via AJAX. – Serendipity May 06 '14 at 14:54
  • Oh yeah Postman just helps see the request and response, but i know the server is generating the file, i no longer get an error infact i get Success printed in the console, it's just that it doesn't kick off the download which i thought would just be automatic handled by the browser but i'm going to have a look at the iframes to achieve it i think – Hagbard May 06 '14 at 14:57
  • The server will always work. There is no problem with the server. It does not distinguish between an AJAX request and a normal request. However, the browser will step in to ensure your javascript does not access the filesystem. – Serendipity May 06 '14 at 15:03
  • Oh okay, so i guess i'm forced to use something like iframes. Just seems so inelegant. Thanks – Hagbard May 06 '14 at 15:05
1

Try this http://jsfiddle.net/abLeR/

It downloads a tar file using hidden iFrame and ajax. Same can be used for the xls file.

HTML

<a class="download" href="http://ftp.neu.edu.cn/mirrors/eclipse/technology/epp/downloads/release/kepler/SR1/eclipse-java-kepler-SR1-linux-gtk.tar.gz">Download</a>
<span style="display:none;" class="loading">Loading...</span>

Javascript

$(".download").click(function (e) {

    e.preventDefault();
    var link = $(this);
    $('.loading').show();

    $.ajax({
        type: 'HEAD',
        url: link.attr('href'),
        complete: function () {

            $('.loading').hide();
            var ifr = $('<iframe />').attr('src', link.attr('href')).hide().appendTo(link)
            setTimeout(function () {ifr.remove();}, 5000);
        }

    });

});
SajithNair
  • 3,867
  • 1
  • 17
  • 23
  • Hi, this example works for the above file, however i need to submit some data to the server first in order to 'generate' the correct file. I've tried the above with the added 'data: JSON.stringify(myJSON)' But no luck. Any idea how i could do this? – Hagbard May 08 '14 at 08:53
  • Can you send those as GET parameters? – SajithNair May 08 '14 at 09:18
  • You can actually use the same parameters (type:post, data:JSON) which you have given in the question. The only thing is that after generating the XLS, you need to store it somewhere on the server (say with a random name) and then the ajax should return this URL value. Then the complete function will get the URL which can be used to set the path for the iFrame – SajithNair May 08 '14 at 09:30
  • Thanks, i've got the code working to my requirements on modern browsers, but getting an error in IE8 with my code, any idea why? I've updated the code above. – Hagbard May 08 '14 at 11:03
  • Can you see if this demo is also triggering same error on your IE? http://jsbin.com/vagajihi/1/edit – SajithNair May 08 '14 at 12:28
  • On my IE 8.0.7600 running on vmware/mac, its not throwing any error – SajithNair May 08 '14 at 12:30
  • That new code didn't trigger an error no, it must be something on my end which is causing the issue. It is working on Chrome and FF though so that's good enough for the time being i think. Thanks! – Hagbard May 08 '14 at 14:34