synergetic
synergetic

Reputation: 8056

Dealing with attachment file in jquery.ajax

In my web page I have a button for downloading a file. If there's no file to download, then I'd like to show a message while staying on the same page. The following javascript code works when there's a file to download (id is file id):

function downloadFile(id) {
    window.location = '/myapp.com/download_file/' + id;
}

My server writes the file content into the response body and sets 'Content-Disposition' header to 'attachment'.

Now, when there's no file I'd like to return some text saying that there was no file to download. So I'd like to do something like below:

function downloadFile(id) {
    $.ajax({
        url: '/myapp.com/download_file/' + id,
        success: function () {
            //if (attachemnt) {
            //    download file: just pass response to the browser?
            //} else {
            //    show error text
            //}
        },
        error: function () {
          //show error message
        }
    });
}

So, my question is:

  1. How can I implement the above functionality?
  2. Specifically, if there's an attachment file in the response, is it possible just to pass the response to the browser, so that the browser can handle file download?

UPDATE: I can handle 'no file' case now:

$.ajax({
    url: '{{ path('download_prev_other_data', {'other_data_id':form.vars.value.getOtherDataId() }) }}',
    success: function (data, textStatus, jqXHR) {
        var header = jqXHR.getResponseHeader('Content-Disposition');
        if (header && header.indexOf('attachment') === 0) {
            //pass the original response to the browser
        } else {
            alert(data); //data is just text in my case explaining there was no file
        }
    },
    error: function (jqXHR, textStatus, errorThrown) {
        alert(errorThrown);
    }
});

So, my 2nd question, "how to pass the original response to the browser" is not answered yet.

Upvotes: 4

Views: 15094

Answers (2)

Saram
Saram

Reputation: 1510

You can not use ajax for file download when rely on standard browser possibilities. I think that best solution is to use hidden iframe.
Create iframe on page startup with empty content and empty src. then when you want to download file just update iframe's src with file url. Before you need to prepare load event handler for iframe. Handler should check iframe content (e.g. body) for error message. If so - you can display custom message.
You can not handle success (afaik) becouse browser automatically handles it and displays 'save as' dialog.

Note:

  • To get iframe body use: $('#frame').contents().find('body').
  • It's browser dependent when load event is trigger for iframe - be ready to handle it also after main page is loaded (empty/initial iframe state)

I think, that you can also consider to use different request for check & for download attachment. Check it with POST request and check on server side whether attachment can be found. If so response OK status, and then use GET request on client side for retrieve attachment. In this case usually window.open is enough to download file. Browser sends GET request itself and handles download.

Note:
Remember to send header with attachment content response, like below:
"Content-Disposition", "attachment; filename=yourFileName"

Upvotes: 0

Piotr Stapp
Piotr Stapp

Reputation: 19828

There is are ready plugin for this with source code: jquery.fileDownload.js Library

Upvotes: 1

Related Questions