jQuery File Download Plugin for Ajax like, feature rich file downloads

jquery.fileDownload.js Library

jQuery File Download is a cross server platform compatible jQuery plugin that allows for an Ajax-like file download experience that isn’t normally possible using the web.

Features

  • Brings control back to the developer by exposing a “successCallback” and “failCallback” that allows the developer to control the user experience in either situation.
  • In conjunction with jQuery UI a developer can easily show a modal telling the user that a file download is occurring, disband the modal after the download starts or even inform the user in a friendly manner that an error has occurred. See the Demo for an example of this.
  • File downloads don’t occur in the current window’s location bar. This means if a failure or something unexpected happens the user doesn’t leave the current page they are on or even have to see an ugly error message. This is critical for a good user experience especially on a highly Ajax application.

A classic problem with browser file downloads – Error handling

In a general case a file downloads occur after a user clicks an <a href=”location“> link. The href in the instructs the browser to browse to the location indicated. This is equivalent to setting the window.location of a page using JavaScript.

When the response comes back the HTTP response headers can contain many different things (in fact almost anything). Here are some examples:

Normal, HTML Response

Content-Type: text/html; charset=utf-8

The above “Content-Type” indicates to the browser that it should parse the DOM in the response and display it to the user. The location in the user’s location bar changes to reflect the address of the just-downloaded content.

Normal, “File Download” Response

Content-Disposition: attachment; filename=Report0.pdf

The above “Content-Disposition” indicates to the browser that the server is trying to invoke a file download in the browser. The browser responds by opening up a file download dialog (or ribbon) for the user to download the file. As a convenience when the browser detects a response like this it doesn’t change the address bar so effectively the user stays on the same page.

Failed, “File Download” Response

Content-Type: text/html; charset=utf-8

As you may have guessed from that ugly highlighter color we’ve got trouble here. The response from a file download error is generally no different from a normal HTML response, the only difference here is that is has an error message as HTML content. The browser will now happily replace your existing page and address with the new error message. Not only have we now displayed an ugly error message to the user but we have also caused them to leave whatever page they were on.

Imagine you have created a nearly exclusively Ajax site like Gmail. A response like this from the server will cause your entire DOM to be replaced by an error message. Imagine this happening to you in Gmail and having to load up everything all over again. Ouch! My current role creating the framework for a highly Ajax application (like Gmail) inspired me to write this plugin for all to use – “web applications” is where the web is going anyways so there has to be a better way…

Another classic problem with browser file downloads – “Happy path” user experience

I probably just caught you thinking this: “well so what… my site never has any problems that cause error messages”… fair enough, but consider this:

  • What is the response time of your web site in terms of serving up static files? Is it instantaneous? Is a user going to immediately look in the far corners of their screen for some sort of a spinning indicator or might they get confused or angry based on their technical prowess? Maybe they are looking at one of these? http://www.ict.griffith.edu.au/images/Animation/netscape_anim.gif (I hope not or you’ve got bigger issues)
  • What if you are serving up a dynamically generated file (perhaps a report of SQL data?) based on user input that may take a few seconds. An average user might expect some sort of indication of what is going on. At the very least from a developer’s perspective it’d be nice if it wasn’t easy for them to hammer the download link a few times (to make it faster of course) wasting cycles across an entire n-tiered application.

I’ve got a solution… just use Ajax to download it!

Good idea! Unfortunately this is not possible due to one key problem:

  • JavaScript, by design, doesn’t have the ability to perform lower level tasks on a users computer out of security concerns. Initiating file download prompts is one of these limitations.

You can certainly use an XMLHttpRequest object to download a binary (or otherwise) file but there is nothing you can do to the response to somehow get it saved on the user’s computer. Flash doesn’t have this limitation, but we really don’t want to get into Flash do we?

Enter jQuery File Download

jQuery File Download overcomes all of the aforementioned limitations of a “normal” browser file downloads. Well how the heck does that work? The concept is nothing new in fact: If you browse around the web you will find plenty of forum posts discussing the same technique, I just wasn’t able to find a succinct easy to use plug-in to do it hence my decision to create this plugin. The answer is:

An iframe and cookie

What?! I have to rely on Web .1 technology to make my Web 2.0 Ajax application user friendly? Turns out this is the magic bullet combination to work around normal limitations of file downloads, here’s how:

iframe

An iframe (which is generally a mortal sin of modern web development) can exist in a DOM but in most respects is treated like an entirely different window. By dynamically inserting a hidden iframe into the DOM and setting its location to the desired file path we can initiate a file download just like it was occurring in the main application window. This directly gets us around one of the nasties of file downloads – if an error occurs the user has now been forced off of the page they were on (which may contain an Ajax application like Gmail) to see an ugly error message.

Like a normal file download in the main window an iframe will never fill with content when a successful file download occurs. It simply contains an empty DOM. Well how do we detect what is going on if nothing happens when the file download is successful. Well this is where the cookie comes in:

cookie + iframe

Since the creation of cookies exists in HTTP headers, which is standard fare for all web requests and responses, we can actually write a cookie to indicate that a file download has been initiated properly (instead of an error page). The response from the web server will now look something like this:

Content-Disposition: attachment; filename=Report0.pdf
Set-Cookie: fileDownload=true; path=/

While we can’t directly tell if a file download has occurred we can check for the existence of a cookie which is exactly how jQuery File Download works. Once a download is initiated on the iframe a configurable duration poll of cookies and the iframe contents occurs. If the iframe fills with contents then we know a file download has occurred (in most cases, make sure to set a MIME type!). If the cookie gets written then we know to stop polling and kill the iframe because the file download dialog/ribbon has been displayed.

Using jQuery File Download – JavaScript

jQuery File Download is easy to use in the simple case but also allows for various callback options as well. Don’t forget to add the required cookie code in the next section!

Very simple code demo

$.fileDownload('/url/to/download.pdf');

 

Use of the very simple approach only protects you from the page changing in the event of a file download error. This alone is pretty useful. If an error occurs the user gets an alert() dialog that says  “A file download error has occurred, please try again.” You can see this demoed here under the “Barebones – jquery.fileDownload.js” heading. I wouldn’t recommend using this option given a much better experience is only a few more lines away…

Impractical code demo of commonly used features

This just demos what you could do but I’d highly recommend against it unless you want confused and annoyed users. This will result in an alert() dialog telling you a file download initiation has just occurred for the specified URL. If a failure occurred it will display the attempted URL and error message in a dialog.

$.fileDownload('/url/to/download.pdf', {
    successCallback: function (url) {

        alert('You just got a file download dialog or ribbon for this URL :' + url);
    },
    failCallback: function (html, url) {

        alert('Your file download just failed for this URL:' + url + '\r\n' +
                'Here was the resulting error HTML: \r\n' + html
                );
    }
});

Simple rich user experience code demo

You can see this one running at the top of the demo page. In order for the below code to work for you, you will also need jQuery UI installed and an image (if you want) as a downloading spinner.

This code will cause any <a> with class=”fileDownload” like below

<a href="http://jqueryfiledownload.apphb.com/FileDownload/DownloadReport/0" class="fileDownloadSimpleRichExperience">Report0.pdf</a>

that is ever loaded into your site (assuming a globally loaded JavaScript reference) to initiate a “rich user experience”:

  • User is informed of a pending report download via a jQuery UI modal that says “We are preparing your report, please wait…”
  • Success:
    • Modal goes away just as the browser’s file download dialog/ribbon occurs
  • Failure:
    • User is informed of an error in a jQuery UI modal: “There was a problem generating your report, please try again.”

Another plus to this approach is that it degrades gracefully in case the user doesn’t have JavaScript running because an a href certainly better work in any web browser out there! 

//the below uses jQuery "on" http://api.jquery.com/on/ (jQuery 1.7 + required, otherwise use "delegate" or "live") so that any
//<a class="fileDownload..."/> that is ever loaded into an Ajax site will automatically use jquery.fileDownload.js
//if you are using "on":
//you should generally be able to reduce the scope of the selector below "document" but it is used in this example so it
//works for possible dynamic manipulation in the entire DOM

//
// Simple rich user experience - jquery.fileDownload.js & jQuery UI Dialog
// uses the optional "options" argument
//
$(function() {
    $(document).on("click", "a.fileDownloadSimpleRichExperience", function() {
        $.fileDownload($(this).attr('href'), {
            preparingMessageHtml: "We are preparing your report, please wait...",
            failMessageHtml: "There was a problem generating your report, please try again."
        });
        return false; //this is critical to stop the click event which will trigger a normal file download!
    });
});

 

 

Custom rich user experience code demo

This demo does almost the same thing as above but handles the modals manually by using the callbacks and it uses modal HTML that already exists on the page.

 

//the below uses jQuery "on" http://api.jquery.com/on/ (jQuery 1.7 + required, otherwise use "delegate" or "live") so that any
//<a class="fileDownload..."/> that is ever loaded into an Ajax site will automatically use jquery.fileDownload.js
//if you are using "on":
//you should generally be able to reduce the scope of the selector below "document" but it is used in this example so it
//works for possible dynamic manipulation in the entire DOM

//
//Custom rich user experience - jquery.fileDownload.js & jQuery UI Dialog
//uses the optional "options" argument
//
$(function() {
    $(document).on("click", "a.fileDownloadCustomRichExperience", function() {

        var $preparingFileModal = $("#preparing-file-modal");

        $preparingFileModal.dialog({ modal: true });

        $.fileDownload($(this).attr('href'), {
            successCallback: function(url) {

                $preparingFileModal.dialog('close');
            },
            failCallback: function(responseHtml, url) {

                $preparingFileModal.dialog('close');
                $("#error-modal").dialog({ modal: true });
            }
        });
        return false; //this is critical to stop the click event which will trigger a normal file download!
    });
});

 

HTML for jQuery UI Modals (place anywhere on page) 

 

<div id="preparing-file-modal" title="Preparing report..." style="display: none;">
	We are preparing your report, please wait...

	<!--Throw what you'd like for a progress indicator below-->
	<div class="ui-progressbar-value ui-corner-left ui-corner-right" style="width: 100%; height:22px; margin-top: 20px;"></div>
</div>

<div id="error-modal" title="Error" style="display: none;">
	There was a problem generating your report, please try again.
</div>

 

Using jQuery File Download – Server Code for Cookie

Only the MVC 3 server code has been tested. Actually if you want to see it running just head over to the demo page. Just make sure to write a cookie in the same HTTP response as the file download occurs with, that results in this HTTP Response Header (using default configuration):

Set-Cookie: fileDownload=true; path=/

ASP.NET MVC 3

If you are using a Controller Action to serve up your files (I hope you are!) you can very easily enable automatic cookie writing by inheriting your Controllers from a base class that writes the cookie automatically for you. This assumes that you are using MVC helpers for returning “FileResult”s (or derived classes like FileStreamResult). MVC FTW.

public class FileDownloadController : Controller
{
    protected override void OnResultExecuting(ResultExecutingContext context)
    {
        CheckAndHandleFileResult(context);

        base.OnResultExecuting(context);
    }

    private const string FILE_DOWNLOAD_COOKIE_NAME = "fileDownload";

    /// <summary>
    /// If the current response is a FileResult (an MVC base class for files) then write a
    /// cookie to inform jquery.fileDownload that a successful file download has occured
    /// </summary>
    /// <param name="context"></param>
    private void CheckAndHandleFileResult(ResultExecutingContext context)
    {
        if (context.Result is FileResult)
            //jquery.fileDownload uses this cookie to determine that a file download has completed successfully
            Response.SetCookie(new HttpCookie(FILE_DOWNLOAD_COOKIE_NAME, "true") { Path = "/" });
        else
            //ensure that the cookie is removed in case someone did a file download without using jquery.fileDownload
            if (Request.Cookies[FILE_DOWNLOAD_COOKIE_NAME] != null)
                Response.Cookies[FILE_DOWNLOAD_COOKIE_NAME].Expires = DateTime.Now.AddYears(-1);
    }
}

 

ASP.NET

Static Code

HttpContext.Current.Response.SetCookie(new HttpCookie("fileDownload", "true") { Path = "/" });

 

Response-aware code

Response.SetCookie(new HttpCookie("fileDownload", "true") { Path = "/" });

 

PHP (with example file)

header('Set-Cookie: fileDownload=true; path=/');
header('Cache-Control: max-age=60, must-revalidate');
header("Content-type: text/csv");
header('Content-Disposition: attachment; filename="'.$title.'-' . $timestamp . '.csv"');

 

That’s it!

Let me know if you have any issues or can think of some nice features to add.

247 thoughts on “jQuery File Download Plugin for Ajax like, feature rich file downloads

  1. Hi John

    Have you tested this script in IE8?

    The file download dialog does not show after the initial file generation (animation) completes. I don't personally have IE8 installed, but used IETester instead and is supposed to give accurate behavior.

  2. Hi Ronnie,

    Thanks for the feedback. Funny thing: I actually noticed the same behavior in IE Tester IE8 mode, the dialog didn't come up. I have fully tested in native IE 6-9 installs and everything appears to work properly in my demo.

    IE Tester is a pretty cool thing for high level testing (I use it for starters on everything that I need cross IE browser support) but sometimes it gets a little weird with things so I'll always finish off testing in a native install. Too bad you can't run multiple IEs on a single box right…

    I'm updating the post to include tested browsers. Let me know if you notice anything else or can think of some cool features to add!

    John

  3. First of all, great Plugin. Really usefull.
    I tried in my webbrowser, working properly.
    Does it work on webkit? I mean it does but actually I decided to include this into my phonegap app (using jQuery Mobile) and when i click the link it leaves the application and redirect to the native browser.
    Did I miss something?

  4. Hey Jeelig,

    Thanks for the feedback. If you are using PhoneGap that actually makes a bit of sense since it probably sees the IFRAME come in (how I implemented this thing) and point at a URL. Without it knowing any better it probably just spawns up a browser to deal with that event since IFRAMEs are generally junk (except in this one case, ha!). Take a look at this forum post I found to help clarify:
    http://groups.google.com/group/phonegap/browse_thread/thread/bd1280d14ff1ff81?pli=1

    Unfortunately this is probably permanent so you may need to find a different solution (perhaps using native code in the device you are targeting even?) Let me know if/what you use to get this figured out!

    John

  5. Hi There!
    First of all, great Plugin!

    But I'm having some troubles trying to use it. Since it never stops, this line

    if (document.cookie.indexOf(settings.cookieName + "=" + settings.cookieValue) != -1)

    Is never true, so it doesn't stop, and no success function is fired. It happens on last versions of FF, Chrome and safary.

    Any clue?

  6. Hi Emilliano,

    Are you writing a cookie along with your file download? Unfortunately this is the only way to detect file downloads reliably cross browser. Make sure (using FireBug, Chrome, Fiddler etc.) that your response headers along with the file download contains "Set-Cookie: fileDownload=true; path=/" or else there is no way for jQuery File Download to know that a file download just occurred. I hope this helps!

    John

  7. Hi John,

    1st of all, very interesting your feature. I am having trouble to use with PHP.

    My Chrome is returning. Do you know why?

    Uncaught TypeError: Object function (a,b){return new e.fn.init(a,b,h)} has no method 'fileDownload'

  8. Hi Ricardo,

    I'm not sure what could cause that issue without doing local debugging of it. Make sure that you have added a script reference to jQuery before your script reference to jQuery file download. Also try calling jQuery file download with the exact same syntax as mentioned in one of my posts to make sure its not a syntax issue (for starters). Hope you get it figured out

  9. Not sure if I've done this right. I have a gaming site and i'm trying to use your script to give the .exe installing apps a better experience for all the reasons you noted. I've included your modal dialog version of the script. Demo here http://www.stimulus.com/my/cTest.php. What I'm not sure is about the server side cookie. I use a redirect script to track all the download requests in PHP. Prior to setting the header location, I'm setting the cookie to your PHP line above. What happens on IE is that the download script reports a failure, but successfully executes the request. On the Mac (which is not really needed at this moment, but will be later) it flashes the processing dialog and doesn't execute the download at all.

    My question is, do I need to set the cookie AFTER the file download has queued or finished? I would have to write a proxy streaming script to know when its done since I'm linking outside my site. Not a big deal, but not something I saw noted in your example.

  10. Hi DrTyrell,

    I took a look at the site indicated and it doesn't appear to be running anymore. The cookie should be written along with the response stream that contains the file. In my examples it looks something like "Content-Disposition: attachment; filename=Report0.pdf" to send the file along with the file bytes. The cookie needs to be included in a header with that. Hopefully this helps!

    John

  11. There is a issue for Firefox, if my FF prompts me selecting the path to download, and at that time, the temp iframe has already been removed, so the download will not continue, anyway can detect the save as dialog?

  12. Plugin is unable to download 'dat' and 'jpg' files. I am not sure whats going wrong? Your comments would be appreciated. Thanks.

  13. Hello John

    I have used the same code that you have given but in simple ASP.Net , What should be the URL Passed in the link , I am giving the path of the pdf, But it is going to the Failure , what could be the reason, I will be really great full if you can help me on this.

    Anuj

  14. For php you have to return the cookie in the header information.

    If you try using setcookie("fileDownload",”true”, 0, "/"); you will get a successful download but the UI dialog box will not close.

    example.

    header('Set-Cookie: fileDownload=true');
    header('Cache-Control: max-age=60, must-revalidate');
    header("Content-type: text/csv");
    header('Content-Disposition: attachment; filename="'.$title.'-' . $timestamp . '.csv"');

  15. Nice, I like it. Provided a solution to a large file download problem I was having.

    I can't help but think though, is the cookie component even necessary? The iframe state can be tested using .readyState, ie:

    if (formDoc.readyState == "complete") {
    //execute specified callback
    internalCallbacks.onSuccess(fileUrl);
    cleanUp();

    see the below article:
    http://stackoverflow.com/questions/6183737/dynamically-create-an-iframe-and-attach-onload-event-to-it

    Am I missing something here? Cross browser compatibility perhaps?

  16. My successCallback is never called because
    if (document.cookie.indexOf(settings.cookieName + "=" + settings.cookieValue) != -1)
    is always false

    On the server side I added
    header('Set-Cookie: fileDownload=true');
    into my PHP with other headers
    I also looked up wireshark and I am sure the Set-Cookie is in the header

    Somehow my browser does not write Set-Cookie in to browser's cookie

    Any idea?

    Thanks~

  17. Hi Stumblor,

    Good idea on checking the iframe's readyState. Your right though, unfortunately when I was testing this approach Chrome didn't work. Each browser that did work had different things happen to the readyState (of course right?) but at least it changed, Chrome's simply wasn't affected at all. Thanks for the thought!

    John

  18. Howdy,

    Just wondering if anyone else has noticed an intermittent failure with this plugin when using Firefox? This is with a "straight" out of the box Firefox install (v13.0.1, in case anyone is interested), and no extensions added.

    I'm seeing this *only* on Firefox. Chrome, Opera, Safari and, yes, even IE(!) work just fine.

    It's easily reproducible for me on the demo page (http://jqueryfiledownload.apphb.com/). 1 in about every 8 clicks on the top "Report0.pdf" will fail silently – that is, the "We are preparing your report, please wait…" dialog disappears but no file save download dialog appears. There is absolutely no indication that anything has gone wrong apart form this.

    When the failure occurs, it's not permanent, and clicking on the link again usually gets me the file (but it still fails intermittently afterwards).

    I've tried to figure out what's going on by installing the FireBug extension and debugging, but I can't track down the difference between the successes and failures. The flow of execution seems the same in both cases. Having said that, I have noticed that:

    a) the presence of the FireBug add-on *seems* to increase the number of failures
    b) if I remove the call to kick off the checkFileDownloadComplete on line 286 of v1.3.0, the problem *seems* to go away (but then, of course, the success/fail callbacks never happen)
    c) similar to (b), if I increase the checkInterval beyond the length of time the file takes to prepare on the back end, the problem seems to go away. For example, if my test file takes 5 seconds to prepare, and I set the checkInterval to 10000 (i.e., 10 seconds), then all is good.

    b) and c) indicate a problem with the checkFileDownloadComplete() method, but it all looks very innocent to me.

    Also, it could just be that I have been lucky and not seen it under those conditions – the usual problem with the intermittent problems…

    It'd be useful to know if anyone else has noticed this issue!

    Apart from this, the plugin is very clever and most awesome – great work!

    Cheers!

    Andrew

  19. Hello John.

    This tool is really useful. I have it working but it would seem that it doesn't work for ALL extensions of files. At least that's my conclusion after trying to download 5 files with the same name but different extensions. Some were downloaded but to the others appeared the "A file downloaded error …" box and didn't download. And it's happening a funny thing in IE. When I request the download, the save box shows up but also the error box (when downloading known extensions).

    Apart form that, nice work!

  20. hey john, thanks so much for jQuery filedownload, it's great.

    i'm stuck on a problem with it and hope you can help, wasn't sure if a message or a post would be better.

    my files are stored in s3 buckets.

    – i generate the s3 auth url on my app server and then pass that url to $.fileDownload().
    – app server sets the cookie fileDownload=true when it returns that generated s3 url
    – i have s3 returning the correct content-disposition: attachment header to force download.

    but no file download is initiated.

    if i hit that s3 generated link in a new tab, it downloads correctly. if i try $.fileDownload() on a file that is served directly from my app server (where i set-cookie fileDownload=true) the download is initiated correctly.

    i can't set-cookie from the amazon s3 server. does that mean i'm out of luck? or is there another way to approach this? does the set-cookie header have to happen in the same response that serves the file

  21. i forgot to add that the download does succeed, the onSuccess callback happens and watching traffic in my http proxy i see that the file does get transferred. the problem is that no file dialog appears to save as, nor does the file download appear in the downloads section of the browser, it seems to just get loaded into the current document invisibly.

  22. ..and here i am again. upon further debugging, i understand the issue here. since i'm making two requests, first to my app server for the generated s3 url, second to s3 using that generated url, the iframe disappears. here's why:

    on the first call to the app server, set-cookie downloadFile=true happens, which checkFileDownloadComplete sees and kills the iframe before it can start downloading from s3.

    but you can't set cookies from s3, so is there a solution here? i'm new to javascript and jquery so i'm not sure. if i don't ever set that cookie, i can use the basic functionality of this plugin, but i would like to use the advanced functionality if i can.

  23. Hi John,
    Your lib accepts a array in [b]'data'[/b] parameters?
    Example:
    A checklist sends a lot of params with the same name, so the server is waiting a list like object.

    Thanks! Great work!

  24. If you are using .Net, beware of the <httpCookies httpOnlyCookies="true" requireSSL="false" /> setting. If you have httpOnlyCookies on you won't be able to read the cookie client side and it won't work. I think this might even be the default option.

  25. [HttpPost]
    public FilePathResult DownloadReportPost(int foo)
    {
    //How do we get values from the entire page here

    string s = "are you getting page contents here?";

    return GetReport(foo);
    }

    In the above, how do I get all values on the form on client (HTML page)?? thanks.

    Lakpak Sher

  26. This is in response to Andrew Laws and anyone else experiencing intermittent failures to get prompted to save a file. The problem appears to be due to the iframe getting removed too quickly. I solved the problem by changing line 369 of v1.3.0:

    setTimeout($iframe.remove, 1000);

    The added delay seems to clear up the problem. A better solution might be to check and see if the iframe already exist when it is being created and if so, remove the existing one first.

  27. I need to use this plugin with coldfusion 9. Here I found demo with ASP.NET & PHP. I want to use this with coldfusion. No idea how to manage code related to cookie as shown for ASP.NET. Any idea?!

  28. I have an odd dilemma. This is using Firefox 15.0 (release).

    If I do not add the SetCookie to the header, my callbacks are called too early.

    If I DO add the SetCookie to the header, it may be 2 or 3 clicks before I see the dialog asking whether I want to open or save the file, but the file save dialog never appears after I click "Ok" on that one. However, the callbacks don't get called until that dialog goes away, which is what I'd expect.

    Any ideas?

  29. Hi Everyone,

    Thanks for the heads up on the Firefox issue and the solution Andrew Laws/Mark. I have updated the GitHub and the demo site with a setTimeout 0 around the cleanup which should clear the stack before cleaning up hopefully fixing the issue. I'm unable to get it to happen now. Anyone please let me know if you can get it to happen again, thanks!

    John

  30. Hi John

    After you've added "var $ = jQuery.noConflict();" to the script and after I implemented System.Web.Optimization for bundling and minification in MVC4, the script will no longer work in IE8.

    The error "'$' is null or not an object" is thrown and then of course numerous "object expected" errors.

    If I remove uncomment that line, everything loads fine. The line causes no problem in other webbrowsers, that I have tested with (IE9, IE10, Firefox, Chrome).

  31. Very interesting plugin and it works for me except for IE7. Trouble in my case is, that the download may be empty, in which case failCallback is used. In IE7, however, this is not enough. After a lot of trial/errors I managed to copy your examples completely and found out that with error code 500 for empty response it works OK in all my browsers.

    But the question is – is there any other way how to treat empty download differently? What if real error occured on the server – then I can't distinguish it from empty response (which I have to mask as 500). I originally tried 404, which was probably deep misunderstanding on my part – this rather refreshed the whole page in the browser.

    I'd welcome any suggestions as I'd love to use this plugin in our future works, it seems quite reliable when I stick to 500 code for errors 🙂 and the experience is just great. Users just can't be talked out of wanting to disable buttons and then enable them again, so we have to use something like this.

  32. @Richard:

    Thanks for the feedback. I have noticed things getting hairy with IE due to the "stock" pages that it presents with certain >= 500 HTTP Response codes. I'm not aware of any way around it at this point unfortunately.

  33. John, I managed after all. I can recognize empty download on server side, so I sent the same cookie but with different value. Then I copied your check of a cookie and callbacks and made emptyCallback available. It is pleasure to work with your jQuery plugin and it was easy to adapt it – even for JS/jQuery newbie like I am. 🙂 Now I have success, empty download and error as three different paths with three different feedbacks for user. Thank you again very much.

  34. Hello John,

    I am having problems with getting the dialog to close. Files are successfully downloaded, but the dialog remains open after the download. I am using the code snippet from your "Custom rich user experience" that employs the 'preparing-file-modal' divs. The cookie is correctly returned in the response header, so I don't believe that is the problem. Also, the text in the dialog "We are preparing your report, please wait…." does not appear. This problem occurs in both Firefox 15.0.1 and Chrome. Any clues on what I should be checking would be appreciated.

    Thanks much, Bill

  35. Hello John,

    I am having a few problems using the code from your "Custom rich user experience – jquery.fileDownload.js & jQuery UI Dialog". The modal dialog opens and the file download completes, but the dialog box does not close. It is not clear that the successCallBack function is ever called. The response header for the downloaded file has the appropriate settings for the cookie, as you describe in the documentation, so I'm not sure what might be broken. Also, the text "We are preparing your report, please wait…" never appears in the dialog. This behavior is true for both Firefox 15.0.1 and Chrome.

    Thanks, Bill

  36. @Bill Hudspeth

    I would try stepping through the jQueryFileDownload source and see why the callback isn't getting called. I don't think it's an issue with the code since it appears to be working in the demo but you never know. If I were to throw a guess out there I would think that perhaps the cookie is being written incorrectly. For example are you writing for path=/?

  37. Hello John,

    Looks really nice! I've been looking for a pluging like this for a while.

    Anyway, short question. Are there any plans to have the filedownload function return an appropriate promise/deferred object? I checked the source code, but couldn't find anything.

  38. @Sumadartson

    Glad the plugin is working for you. That's a great idea to include the promise/deferred interface. Perhaps I can include that in a future commit. Feel free to contribute on GitHub in the mean time if I don't get to it for awhile. Thanks!

  39. Hi John,

    Using version 1.3.3 I noticed the following browsers behaviors : IE9 (9.0.8112.16421) and Safari 5.1.7 don't properly handle the file download when http method is POST (I need to use POST rather than GET because I may send a lot of data from page): file downloads but there is no prompt for user to do something with file data (save, open…). I searched on the internet and send you a diff file (I don't have a github account, sorry) for the following changes : add a name for iframe, target form to it. For both browsers I quoted above, rather set target to _blank.
    I saw that non-hidden iframe will show a PDF document (the only kind of file I tested) for IE9 if targeting form to it. But its default size is unpractical. For browsers which prompt user, non-hidden frame border is visible, and it just blinks on file download, right before prompt displays.

    Finally I wonder whether I've found something specific to PDF files, related to PDF preview in browser plugin being installed ? Thank you for your feeback about this and the patch I propose.

    Thank you for this great plugin,

    — eaa_jquery.fileDownload-1_3_3.js 2012-10-15 10:33:31.711876000 +0200
    +++ eaa_jquery.fileDownload.js 2012-10-16 11:37:09.265816700 +0200
    @@ -115,8 +115,12 @@
    var isIos = false; //has full support of features in iOS 4.0+, uses a new window to accomplish this.
    var isAndroid = false; //has full support of GET features in 4.0+ by using a new window. POST will resort to a POST on the current window.
    var isOtherMobileBrowser = false; //there is no way to reliably guess here so all other mobile devices will GET and POST to the current window.
    + var isTargetNewWindows = false; //there are browsers like some versions of IE9, Safari 5, which don't open user prompt after file download with POST method to iframe, so use blank target.

    – if (/ip(ad|hone|od)/.test(userAgent)) {
    + if (userAgent.indexOf('trident/5.0') != -1 || userAgent.indexOf('safari/') != -1) {
    + isTargetNewWindows = true;
    + }
    + else if (/ip(ad|hone|od)/.test(userAgent)) {

    isIos = true;

    @@ -127,7 +131,6 @@
    } else {

    isOtherMobileBrowser = /avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|playbook|silk|iemobile|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i.test(userAgent.substr(0, 4));

    }

    var httpMethodUpper = settings.httpMethod.toUpperCase();
    @@ -270,32 +273,28 @@
    .html(formInnerHtml);

    } else {

    + // POST method
    if (isIos) {

    downloadWindow = window.open("about:blank");
    downloadWindow.document.title = settings.popupWindowTitle;
    formDoc = downloadWindow.document;
    window.focus();

    } else {

    – $iframe = $("<iframe style='display: none' src='about:blank'></iframe>").appendTo("body");
    + $iframe = $("<iframe style='display: none' src='about:blank' name='my_iframe'></iframe>").appendTo("body");
    formDoc = getiframeDocument($iframe);
    }

    – formDoc.write("<html><head></head><body><form method='" + settings.httpMethod + "' action='" + fileUrl + "'>" + formInnerHtml + "</form>" + settings.popupWindowTitle + "</body></html>");
    + var myTarget = isTargetNewWindows ? "_blank" : 'my_iframe';
    + formDoc.write("<html><head></head><body><form method='" + settings.httpMethod + "' action='" + fileUrl + "' target='" + myTarget + "'>" + formInnerHtml + "</form>" + settings.popupWindowTitle + "</body></html>");
    $form = $(formDoc).find('form');
    }

    $form.submit();
    }


    //check if the file download has completed every checkInterval ms
    setTimeout(checkFileDownloadComplete, settings.checkInterval);


    function checkFileDownloadComplete() {

    //has the cookie been written due to a file download occuring?
    @@ -375,7 +374,7 @@

    function cleanUp(isFailure) {

    – setTimeout(function() {
    + setTimeout(function () {

    if (downloadWindow) {

  40. Hi John,

    great plugin, and indeed very useful.

    Tested v1.3.3 on OSX 10.7.5 – FF 16.0.2 and Safari 6.0.1.

    I tried to throw an error response for the form example (in my case, the php file echoes some html as a warning for no data to be downloaded):
    – OK in FF
    – in Safari it looks like the try/catch part in checkFileDownloadComplete() (line #318) is never reached, being always intercepted by the preceding check for cookie existence (line #302).

    Switching the order of the two statements everything works fine.

    Is it me or anybody else had the same behavior?

    Thanks, Gianni

  41. This plugin does not work if Content-Disposition: inline; is returned. pdf file is not opened in new tab. Nothing happens. How to open pdf file in new tab using this?

  42. I implemented the code in vb.net but it does not work.No error in show but it just does not download.

    code used in server side
    HttpContext.Current.Response.SetCookie(New HttpCookie("fileDownload", "true") With { _
    .Path = "/" _
    })
    ——————————————————-
    Javascript to fire on onclick

    function downfile()
    {
    try
    {
    //alert("entred");
    var linkHref = "http://anywebsite.com/images/1.jpg&quot;;
    $.fileDownload(linkHref);
    }
    catch(e)
    {

    }
    }

    Can any body guide me with this.

  43. Hi John,
    First of all thank you for the wonderful script. Saved a lot of time in exporting the file to Microsoft Excel and download the same from the server.
    Though I could force download the file which was opening the file dialog, I was looking at an option where the download success message was displayed on the user screen. You script help me do it. I did have a small glitch in the code. In your example for PHP you have set the cookie name to be 'fileDownload' and its value to 'true'. For some reason the condition where the cookies are checked for equality failed (ver 1.3.3 line # 304). So I got the PHPSESSID cookie value and set the same for the options in the script. Now the onSuccess call back got a hit. But unfortunately, the cookie was being removed and this used to expire my session. I commented out the cookie removal code and its working fine. I am yet to test further to see if there is any issues in commenting out the code in your script. Looking forward to your suggestions and any corrections to the approach I adopted.

    Thanks,
    Girish

  44. Hi John,
    First of all thank you for the wonderful script. Saved a lot of time in exporting the file to Microsoft Excel and download the same from the server.
    Though I could force download the file which was opening the file dialog, I was looking at an option where the download success message was displayed on the user screen. You script help me do it. I did have a small glitch in the code. In your example for PHP you have set the cookie name to be 'fileDownload' and its value to 'true'. For some reason the condition where the cookies are checked for equality failed (ver 1.3.3 line # 304). So I got the PHPSESSID cookie value and set the same for the options in the script. Now the onSuccess call back got a hit. But unfortunately, the cookie was being removed and this used to expire my session. I commented out the cookie removal code and its working fine. I am yet to test further to see if there is any issues in commenting out the code in your script. Looking forward to your suggestions and any corrections to the approach I adopted.

    Thanks,
    Girish

  45. Great plugin, John! I had some problems getting successCallback to fire, but found the problem after a little while. You can save future PHPers a little confusion if you change your PHP example as follows:

    header('Set-Cookie: fileDownload=true'); // no workie

    to

    header('Set-Cookie: fileDownload=true; path=/'); // no workie

  46. Thanks for the plugin! I'm able to get it working on all browsers. But in iOS, if popup is enabled, I can not get the new tab to load. Any way to bypass that?

  47. Hello;

    Great plugin this is amazing! I do have a question although I think I know the answer I thought I'd ask anyways. In your example using MVC you return the value of FilePathResult to the method. Is it possible to use the HttpResponseMessage and actually return a file that's in memory? The case I have is that I'm generating the file on the fly and trying to download it using your amazing plugin. Any help would be great! Thank you very much.

    1. Hello!

      I am trying to do the same thing as Jason. Is there a way to download a file that exists only in memory?

  48. Hi

    Great plugin! I do have a question though: I want to perform various other ajax operations while the download is in progress (my downloaded file takes a while to create on the server). On the server I keep track of how much progress the 'file building' has made. After my call to $.fileDownload(…) I want to regularly call another ajax.get method which will let me update a progress bar with accurate values.

    At the moment (unless I've configured it wrong), any ajax calls I make after $.fileDownload(…) are queued up and only get executed after the file download has completed. I've even tried adding a $.get(…) call inside the 'checkFileDownloadComplete' function, but it still gets queued.

    Is there any way to achieve this functionality?

    Thanks!

  49. Hi,
    first of all thanx for this plugin, which is very useful indeed…
    I'm having though an issue when downloading a pdf on iPad in full screen mode.

    Doing a little research on google, it turns out that window.open on a full screen web app doesn't work,
    and should be substituted with the normal href action of the link.

    Is there a way to get this plugin working for an iOS web app working in full screen mode?

    Thanks,
    Simone

  50. I have a problem retrieving files address with folder.
    For instance, ./invoice/invocie_1.pdf became ._invoice_invocie_1.pdf
    anyone knows why ?
    Thx
    – Kiko –

  51. Hi John

    I am trying to use the plugin for a DotNetNuke site, I need to allow user to download a PDF which is already created at path somewhere at website/desktopmodules/download/file/path/of/file.pdf but at line 370 of plugin it is saying "Permission denied to access property 'body'" …what is this…i am stuck on this feature and need it urgently as it is really a great plugin to use. jquery code i have used is as below :
    $.fileDownload(r.d, { preparingMessageHtml: "We are preparing your report, please wait…",
    failCallback: function(html, url) {
    alert('Your file download just failed for this URL:' + url + '\r\n' +
    'Here was the resulting error HTML: \r\n' + html);
    }
    });
    Where r.d is a nested path to pdf. Please suggest on what step I am wrong. Thanks for the plugin 🙂

  52. Could you please tell How we can set the responseHtml(used in fail callabck) from server, from where we are getting this value

  53. Hi All,

    Download processing is fine but after downloading the file dialog is not closing.I have read the comments and i have come to know the problem is that need to add setCookie method but where i have to place this bit of code. i haven't get an idea.Now am working on Spring MVC so could any one please help me ASAP.I will be greatly if help. Thank you in advance.

  54. Is it possible to add request headers to the download request or does everything have to be in the URL as query string parameters? Since this is basically driving an IFRAME, my suspicion is that it's not possible to augment the request in this manner, but it certainly doesn't hurt to ask!

    1. Hi John,
      You mentioned you will try to get the request headers done soon. Did you get a chance?

      I’m looking to add some custom request headers to my download request.

      This is need for security.

      Thanks,
      Ashok.

      1. Hi Folks,

        Unfortunately there isn’t any way to do custom headers with an IFRAME (which is the only way to do this currently). An IFRAME must be a get request but you could of course set custom cookies (which are headers) with JavaScript before you make the request. Thoughts?

      1. Hi John,
        You mentioned you will try to get the request headers done soon. Did you get a chance?

        I’m looking to add some custom request headers to my download request.

        This is need for security.

        Thanks,
        Ashok.

        1. Hi Folks,

          Unfortunately there isn’t any way to do custom headers with an IFRAME (which is the only way to do this currently). An IFRAME must be a get request but you could of course set custom cookies (which are headers) with JavaScript before you make the request. Thoughts?

  55. I am working on implementing this wondeful solution but am having a problem with the jquery Dialog creation.

    I have the following Javascript includes:

    Any reason whey it crashes on this line in fileDownload.js:

    $preparingDialog = $(“”).html(settings.preparingMessageHtml).dialog(settings.dialogOptions);

    It would appear that something is amiss with the jquery dialog but the Javascript files are being correctly referenced…

    Thoughts?

    TIA!

    1. oops forgot to remove the html formatting so the references for the JS files would show up, so…

      script src=”/Scripts/jquery-1.8.3.min.js” type=”text/javascript”
      script src=”/Scripts/jquery-ui-1.8.20.min.js” type=”text/javacript”
      script src=”/Scripts/jquery.fileDownload.js” type=”text/javascript”

        1. Hi BC,

          Thanks for the feedback. I looked into it and I’m having no problems with 1.8.3 in Chrome. I have a feeling there might have been something else going on as well. Thanks for letting me know though!

  56. Hey John,
    I have some trouble with your JS. I get the message from the IE Debugger, that a method or property with the name fileDownload not exists. I have these three References.
    script src=”Scripts/jquery-1.9.1.min.js” type=text/javascript”
    script src=”Scripts/jquery-ui-1.10.2.custom.min.js” type=text/javascript”
    script src=”Scripts/jQueryFileDownloadPluginv1.4.0.js” type=text/javascript”
    Do you have some tips.
    Regards Michael

  57. Hi, nice work!!

    I’m experiencing a problem with IE8, complaining about security (Internet Explorer Information Bar): “internet explorer blocked this site from downloading…”.

    Is there a fix for this? I mean, a code fix, because changing the security options of Internet Explorer is not a possibility: I cannot tell all my users to do so…

    Thanks in advance
    Cheers

    Pierpaolo

  58. Hi John, good job, I have this problem: I have to distinguish the session expired error from the other possible errors, in the first case the server sends back a 401 status code, but from what I understood the only thing I can have in the failCallback is the html and not the http status codes, am I right?

    1. There isn’t any way to do this with the plugin. If I were you I would just hit an ’empty’ endpoint on the server with AJAX before you call jquery file download and see if you get the expected response back. If you do then call jquery file download

  59. Could you please tell How we can set the responseHtml(used in fail callabck) from server, from where we are getting this value

  60. Looks quite cool, but if the cookie is just named “fileDownload” than doesnt that mean that it can only manage a single download file at a time?

    In my case I am triggering the download of multiple large images. Once the first one is done all the others will think they are done as well..

    Would it not be better for each instance to have its own unique cookie name to test?

  61. Great plugin!!! But it looks that I’m in the IE hell…It always triggers the failCallback with IE even when the report downploads successfully!!!! no problem with other browsers. Somebody had this before?

  62. Hello and thank you for your plugin.
    I have a question: what if the client browser doesn’t accept cookies? What happens?

  63. Thanks! Saved me a few hours doing it myself… Haha! Who am i kidding… This plugin ROCKS! Tried to implement an iframe/AJAX based download solution myself after i did a simple upload one, but got bitten… You rock thanks John!! Saved me a LOT of time and headaches!

  64. Oh my goodness! Incredible article dude! Many thanks, However I am having problems with
    your RSS. I don’t understand the reason why I can’t subscribe to it.

    Is there anybody else having identical RSS
    problems? Anybody who knows the solution can you kindly respond?

    Thanks!!

  65. I put the line:
    document.cookie = settings.cookieName + "=true; path=" + settings.cookiePath;

    at the end in the onPrepare-function.

    By that I did not need to have it set by code.

  66. Sir this article is verry helpfull base on the article u wrote but Sir may i ask if u have version for 2010 visual studio our company is know developing using 2010vs so i cant view the project

    thanks..

  67. I am trying to use this functionality from a button on a modal dialog so that they can view a PDF form to confirm the data on the modal dialog. It refuses to open the file although I have it referencing a link on the same page the dialog reads itself from. Any ideas about this condition?

  68. Hi John

    In IE8, when I tried to download by second time, the page was blank.
    My site is developed in asp.net.
    Can you help me?

    thanks,

  69. Have anyone gotten this done in PHP or webforms? The guide isn’t super beginner-friendly, I’d like a simple example, just to know the general setup with the headers and the iframe and so on. If anyone could be helpful, that’d be great.

  70. HI..,

    I am using this javascript for blackberry app, but it is not working in blackberry v5,v6 & v7. It is not showing any prompt for the users to download the file.

  71. John,

    This plugin looks very cool. I see from the download you are making it beginner friendly too. The one thing missing is a license statement. I assume you are doing something like MIT / GPL dual licensing? If you throw a license file in there it will make us corporate types more comfortable.

    Thanks

  72. Hi,

    I’m using this plug-in on my webpage. Let’s say my webpage is at A.com, but the file I’m downloading is at B.com. Problem arises only in IE where it does not see the cookie returned by B.com. It treats it as a third-party cookie or god knows what. Tried changing IE privacy settings to allow third-party cookies but it still does not work.

    Any clues on how to get around this?

  73. Well thanks, that is great. i was trying to accomplish something similar but i stepped into this solution and it was all i needed.

  74. Hi!

    Thanks for the plugin!

    I’m having issues with safari downloading pdf’s. They stay opened at the hidden iFrame, don’t know why!. I used the headers, but if I force the download (example: Content-Type: application/force-download), It downloads the php page, not the pdf document!!! When I look for the hidden iFrame, it has the following headers: Content-Type: application/pdf. I imagine that Safari just opens the pdf instead of downloading it!. With other file types it works great and Firefox saves my pdf’s just as expected.

  75. Hi,

    I have tried with plugin with iPad. But this does not work on iPad as the URL to file download is actually a ASP.NET Handler instead of normal HTML document due to which “downloadWindow.document is undefined” error is coming.

    Please provide the updates for Handler pages.

    Thanks

  76. It is, however, feasible for an expert to crack these regular encryption methods.
    It runs very smoothly and quietly from the background of the Mac.
    Taking a cue from that, if publishers may make their ebooks open to a larger audience instantly, it could and will encourage readers to go for that authentic version.

  77. Hi John,

    First of all, great Plugin, and Excellent post!

    Can I use it without MVC callback? but ordinary asp.net button onclick event?
    I means,
    I have asp.net button with OnClick event that on postback to server side I’m loading the file data from DB.

    I want $.fileDownload to access my btnDownloadFiles_Click(object sender, EventArgs e) event and download my dynamic load file.
    I allready have implemented btnDownloadFiles_Click with Response.Write(fileData);
    All I need is how to combite $.fileDownload with btnDownloadFiles_Click event?

    Avi.

  78. Hi John

    I am using CodeIgniter. I can successfully use your plugin except when I enable secure cookies. This (secure cookies) is a requirement! Hence the plugin cannot determine the success of the download by reading fileDownload=true (it’s obviously encrypted in the cookie). Is there a way to send success via a different / special response header?? IF so, how would I modify the plugin to allow for that?

  79. Is there a way to prompt the user with a “save as” dialog box & have the user specify the file name & path (rather than the file downloading to the default download folder with whatever default name)?

      1. I’ve set the content-disposition and set-cookie headers but am not receiving the save as dialog. Any pointers?

        1. Nevermind, it appears to be that Chrome ignores this and always directly downloads. Doesn’t appear to be an issue with your code. Thanks!

  80. I’ve implemented this in MVC using your FileDownloadAttribute and my own jquery. It works as expected/desired except that if you make the request multiple times, each subsequent request will result in multiple file dialogs appearing. The first time, one dialog appears. The second time, two dialogs appear. The third time, three appear. And so on. When I refresh the page, it reset this. Why would this be?

    1. Doh. My fault. The click event was being bound multiple times to my button. I had to call unbind to make sure it was only bound once. Great tool!

  81. John

    I have implemented this in an asp.net project, it works with zip and pdf, but does not with txt files. ¿have you tested with this kind of files?

    thanks in advance

  82. Years later I still love this plugin. One thing that I think is a *no* but I’m not certain – is it possible to do content negotiation with this?

    I have a route /some-report/render which will return either pdf or powerpoint depending on the submitted Accept header. Is that possible with this plugin? Is there any reliable way to trigger downloads where it *is* possible?

  83. Years later I still love this plugin. One thing that I think is a *no* but I’m not certain – is it possible to do content negotiation with this?

    I have a route /some-report/render which will return either pdf or powerpoint depending on the submitted Accept header. Is that possible with this plugin? Is there any reliable way to trigger downloads where controlling your Accept header *is* possible?

  84. Magnificent goods from you, man. I have remember your
    stuff previous to and you’re simply extremely excellent.
    I really like what you have got here, certainly like what
    you are saying and the best way by which you say it. You’re making it enjoyable and you still care for to
    keep it sensible. I can’t wait to read far more from you.
    That is really a terrific site.

  85. Hi John,

    first of all,
    thank you for your very useful plugin!

    I implemented it mixing two of the solutions you’ve shown as:

    function manageDownloadWaitingPopup(event,form,waitingMessage,failureMessage){
    var $preparingFileModal = openWait(waitingMessage);
    $.fileDownload($(form).prop(‘action’),
    {
    successCallback: function(url) {
    $preparingFileModal.dialog(‘close’);
    },
    failCallback: function(responseHtml, url) {
    $preparingFileModal.dialog(‘close’);
    openAlert(failureMessage);
    },
    httpMethod: “POST”,
    data: $(form).serialize()
    });
    event.preventDefault(); //otherwise a normal form submit would occur
    }

    I had already some functions that I wanted to reuse (openWait and openAlert)
    This is the case of the openWait() method, which returns the id of the div used as dialog, and then this id is used in the successCallBack and failCallBack to close it.

    $(“form”).on(“submit”, function (e) {
    var action = $(this).attr(‘action’);
    if(action == ‘downloadTemplate’){
    manageDownloadWaitingPopup(e,this,’Downloading template…’,
    ‘There was an error in the process’);
    }
    });

    All this thing works fine on chrome, but in Explorer, if the download process goes wrong, the dialog doesn’t close. (When the download goes well, it cloes fine).

    Being suspicious, I tried the example from your page, the one with the action that uses the form,
    and when I put an odd number to make the download fail, the dialog does not close.

    It looks like there’s a problem on Explorer just when you use the:

    $.fileDownload($(this).prop(‘action’), {….

    Like it does not catch the failCallback…

    Any idea?

    1. But Actually It’s not because the failCallback.

      The example in your test page has:

      preparingMessageHtml: “We are preparing your report, please wait…”,
      failMessageHtml: “There was a problem generating your report, please try again.”,

      so it looks like the failure makes Explorer go mad… :S

      Any suggestion?

  86. of course like your web-site but you have to test the spelling on several of your posts. Several of them are rife with spelling problems and I find it very bothersome to inform the reality on the other hand I will certainly come again again.

  87. And if you’re not in the mood to brave the parking lot, Jimmy – C’s delivers via Dial and
    Dine. Just search “gourmet teas” or visit your local gourmet shop.
    Many gourmet coffee sites offer dozens of different coffees, including special
    blends for the Christmas season.

  88. Does your blog have a contact page? I’m having problems locating it but,
    I’d like to shoot you an e-mail. I’ve got some suggestions for
    your blog you might be interested in hearing. Either way, great
    blog and I look forward to seeing it expand over time.

  89. Hello,

    I have a form where I am using Jquery validator for server as well as front end validation[AJAX]. Once validations are passed i.e response = SUCCESS, I am creating a dynamic form and calling the method which download a form.
    I have a couple of questions
    1) Is your code below – going to work correctly for dynamic form as well:
    $(document).on("submit", "form.fileDownloadForm", function (e) {
    $.fileDownload($(this).prop('action'), {
    preparingMessageHtml: "We are preparing your report, please wait...",
    failMessageHtml: "There was a problem generating your report, please try again.",
    httpMethod: "POST",
    data: $(this).serialize()
    });
    e.preventDefault();
    });

    2) I am not allowed to use POST as I am getting ethod not allowed error, can I use GET instead of POST in your above code?

  90. Hi,

    I can’t seem to get onSuccess to fire on client side. Server side I do add fileDownload cookie in header.
    This is my Request and Response:

    Request Headersview source
    Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Accept-Encoding:gzip,deflate,sdch
    Accept-Language:en-US,en;q=0.8
    Connection:keep-alive
    DNT:1
    User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
    Query String Parametersview sourceview URL encoded
    id:96f75f1c7de56f162f2719
    reportId:1b479139-f2f7-4fc7-9e25-c13965666fa0
    lang:
    detail:true
    row:1341
    name:4c Full M0 KSS 615_PANTONE coated
    filter:
    predFilter:
    measFilter:
    order:
    Response Headersview source
    Content-Disposition:attachment; filename=4c Full M0 KSS 615_PANTONE coated.pdf
    Content-Encoding:gzip
    Content-Type:application/octet-stream
    Date:Tue, 20 May 2014 21:46:36 GMT
    Set-Cookie:fileDownload=true; path=/
    Transfer-Encoding:chunked
    Vary:Accept-Encoding, User-Agent

    What else can I do to debug this?

  91. Hello,

    I have a controller written in PHP which creates a zip file from some given files and fires up a download dialog in the browser in the template file upon the click of a button. I retrieve back the data from the controller with a jQuery ajax success event which reads the json data provided by the controller. I want to have a progress bar in the template file which reflects the download dialog in real time and which closes when the download is complete. Is this possible with jQuery.fileDownload?

    I set up a cookie in the controller when the zip file and zip url is created, but when I click the button in the template file, the download fires up but the download iframe stops, not reflecting the download process in real time…

    Thank you!

  92. Hi

    I’m using your plugin to download .txt files from server on click of a button. I’ve attached
    .done(function () { alert(‘File download a success!’); })
    .fail(function () { alert(‘File download failed!’); })

    I don’t get any error but there is no file downloaded. Any idea why?
    I attach the headers response:

    Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    Accept-Encoding:gzip,deflate,sdch
    Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
    Connection:keep-alive
    Cookie:language=ro; __utma=212744982.1785255340.1395749984.1399903687.1401719385.5; __utmz=212744982.1401719385.5.5.utmcsr=school360dev.school360.co.uk|utmccn=(referral)|utmcmd=referral|utmcct=/resourcespage/index.php; PHPSESSID=lvmaoccvd7su7117ssj82ek4h7; fileDownload=true

  93. I see a lot of interesting articles on your website. You have to spend a lot of time writing, i
    know how to save you a lot of time, there is a tool that
    creates unique, google friendly posts in couple of seconds, just type in google – k2 unlimited content

  94. Hello John i really appreciate your contribution, i am happy about that.please i have some couple of your favor to ask. i am currently testing your sample API with my java app, i am using java-restful web service + glass fish as the server ,i also use jquery Ajax i imbedded into my HTML to consume the restful web service.i tried jQuery file Download API, in my case it dose not work and i do not know how to set the header in this case. please if you wouldn’t mind could you be of help to me in this challenge ? i thank you again for your contribution co-operation in this field.

  95. Hi,

    I have a problem when using this in IE and Safari. Works fine using FF and Chrome. But in IE and Safari no download window appears. It goes to the success section in the code but still no download window. Could it have anything to do with that that I recently added contextPath to my site? According to IE’s network tab it doesn’t seem to get any response headers from server:

    Protocol Method Result Type Received Taken Initiator Wait‎‎ Start‎‎ Request‎‎ Response‎‎ Cache read‎‎ Gap‎‎
    (Pending…) POST (Pending…) (Pending…) 0 B (Pending…) click 16828 0 328 0 0 -13953

    But still the plugin finds that filedownload cookie.

    Any ideas?

    1. Hi Jake, did you get this resolved? I am getting the same error. It might be related to IE security setting, but I can’t change it because this is a company browser.

  96. Hi, I’m using this plugin in my java code and work fine with Firefox and Chrome but doesn’t start the download with Internet Explorer.
    I set these headers:

    response.setHeader(“Set-Cookie”, “fileDownload=true; path=/”);
    response.setHeader(“Content-Disposition”,”attachment; filename=”+file);

    and in my javascript I use this code:

    $.fileDownload(“/async/paas/caaas/downloadCertificate/”+serialNumber, {
    successCallback: function (url) {
    },
    failCallback: function (HttpServletResponse, url) {
    $(“#modalDownloadFailedCertificate”).modal(“show”);
    }
    });
    return false;

    Someone has the same problem?
    Thanks in advance

  97. hey i used that code and i got some error during downloading.

    Resource interpreted as Document but transferred with MIME type application/pdf: “http://www.hh.example.com/nodejs/pdf/scrapbook205095.pdf”.

    please help me to resolved that error

    Thanks

  98. hey i used that code and i got some error during downloading.

    Resource interpreted as Document but transferred with MIME type application/pdf: “http://www.hh.example.com/pdf/205095.pdf”.

    please help me to resolved that error

    Thanks

      1. I’ve followed your suggestion but the message did not change. I’m using .NET MVC 5. I’ve cleared the headers before set cookie + content-type and the others required headers. Chrome version: 68.0.3440.84

        By the way, congrats for the job.

  99. John,

    I got things to work as expected – if I request a file it downloads. If the requested file doesn’t download I get an error. However, if the file exists and starts to download and then something bad happens (e.g. file is deleted on the server), I don’t get an error as I was hoping. Just wondering if I was doing something wrong or if it’s not possible to return an error once the download has started (which is what I suspect).

    Thanks.

  100. Hello John, thank you for your work.

    I have implemented your ajax plugin, it works in google chrome and firefox, but in internet explorer 11, I have the following error when I do click to the button relationed with the file download plugin.

    Exception uncontrolled line 4,
    12122 column in
    http: // localhost: 16439 / Content / themes / plugins / jquery-1.10.1.js

    0x800A01B6 – Runtime Error JavaScript:
    Object does not support property or ‘attachEvent’ method

    I have readed that the method attachEvent is not supported in IE11, it has to be replaced by the event addEventListener in all the scripts implicated, I have done it, but the error continues appearing. I return the file like in the examples of your web. Is compatible this plugin with IE11?

  101. Hello again, the problem was the iframe, so, I have done it with a modal window, like this example:

    html

    We are preparing your report, please wait…

    There was a problem generating your report, please try again.

    javascript
    $(document).on(“click”, “a.fileDownloadCustomRichExperience”, function () {

    var $preparingFileModal = $(“#preparing-file-modal”);

    $preparingFileModal.dialog({ modal: true });

    $.fileDownload($(this).prop(‘href’), {
    successCallback: function (url) {

    $preparingFileModal.dialog(‘close’);
    },
    failCallback: function (responseHtml, url) {

    $preparingFileModal.dialog(‘close’);
    $(“#error-modal”).dialog({ modal: true });
    }
    });
    return false; //this is critical to stop the click event which will trigger a normal file download!
    });

    Thank you, so be carefull with the iframes in IE.

  102. Hello, that’s me again, the solution is this, the attachEvent doesn`t work in IE11, so it must be replaced by addEventListener.

    Something like that:

    var isIE11 = !!(navigator.userAgent.match(/Trident/) && !navigator.userAgent.match(/MSIE/)); if (isIE11) {

    if (typeof window.attachEvent == “undefined”
    !window.attachEvent)
    window.attachEvent = window.addEventListener;

    }

      1. No, I think your code is great. The problem was jquery and IE11, my solution was to change the jquery, but I work with this jquery modified only in the part of my app that uses your plugin, because I don’t want to take risks changing this for all the app. I use jquery_1.10.1.js. Thanks for your job John, your plugin is awesome.

  103. Grab your subscription and download gossip girl episodes.
    eval(ez_write_tag([[336,280],’brighthubpm_com-box-1′]));.
    A person of the first points to consider previous to building a torrent is which site
    it will be uploaded too.

  104. Hi, nice plugin. However, it seems I cannot get it to work. I believe I have followed the instructions, but I get an “uncaught TypeError: undefined is not a function” in Chrome, where it has highlighted $.fileDownload. I have included jQuery before using the plugin.

    1. This may happen when you have a jQuery.noConflict() function call somewhere (it happened to me two weeks ago because of such a call in Superfish). noConflict is a very useful function when the page already uses another JavaScript library/toolkit that had “$” already mapped to something. However, when jQuery is your main toolkit, the function call has the unwanted effect of leading to the “$ is undefined”. The reason is that noConflict returns the “$” identifier to whatever was its value before jQuery bound to it during its initialization. See the documentation.

      You should search the JS code that your page loads for a noConflict call and maybe remove it. Alternatively, and it’s much simpler, you can replace “$.fileDownload” with “jQuery.fileDownload”.

  105. Hi,
    I have problem with a .txt or .qdp
    Don’t download open in browser.

    $.ajax({
    type: “GET”,
    url: “downloadSed.jsp”,
    data: someData,
    dataType: ‘text’,
    success: function(response){

    $.fileDownload(response);
    }
    })

    In the servlet i have
    response.getWriter().print(toDownload);

    where toDownload is the url of the file in the filesystem.

    i try many combinations of setting in servlet (setcontent) or dataType in Ajax
    Can you help me?
    thanks

  106. HI ,

    thanks for your work it is really helpful. I got this to work but I want to allow the user to start a new download before the first one has completed. It seems that the second click prevents the first download to complete. Do you know how to have parallel download work properly.

    Many thanks,
    Martin

  107. Hi,

    Thanks for this great plugin. I tried it and worked perfectly. I’d like to ask if it’s possible to call the fileDownload to work in the background and also specify a folder location for the downloaded file?

    Thanks for the good work.

  108. Thank you for great plugin! I got it working perfect. But I could not make Pdf display in browser. It always return Download Dialog box.

    my project is asp.net MVC 5. And being try:
    response.AppendHeader("Content-Disposition", "inline; filename=report.pdf");
    Or
    response.AppendHeader("Content-Disposition", "application/pdf; filename=report.pdf");

    Thanks again

  109. John,

    Thank you so much for creating this. It worked great, with one small exception, it didn’t work with safari when on a server with https. To fix this, on the server side when I added the required cookie I had to set “X-Frame-Options” to “SAMEORIGIN”.

    Thanks again for your efforts!

    -eric

  110. Hello john,

    I am creating an application in Zend Framework 2 using your plugin to give feedback to the user after completion of downloading a report.
    I’m finding an error. I use the console to identify whether the download has completed or failed (‘done’ or ‘fail’). In some requests the plugin returns “fail” even download being completed or being in progress.
    Also encounter difficulties in downloads when the browser opens a window to choose the file directory. At this time returns fail. This is a bug in Chrome.
    These errors only occur when using Apache server. When I use the PHP internal server it does not give this error.

    Any idea what may be happening in both cases?

  111. If you are using MVC and can’t read cookie at client side and have “; HttpOnly” in your cookie string, then you simply change cookie creation line to “response.AppendCookie(new HttpCookie(this.CookieName, “true”) { Path = this.CookiePath, HttpOnly = false });”. HttpOnly might be on by default in MVC5.

  112. Hi John,

    This plugin worked like a charm in MVC. But now I need to implement it in ASP .NET Web forms, and it doesn’t look like a walk in the park. Can you make a ASP .NET webforms example as well. Would greatly appreciate it!

  113. Hello John,

    Ive used the plugin couple of times and has worked like charm. Currently I am using the plugin to download an excel file which would get created from the data retrieved from the database. I am using java servlets. The download is working fine but I wanted to send some specific messages back to javascript. Is there anyway I can do that from within your script? or use exiting parameters to get the data sent from the server as JSON string? Whatever I send back is getting embedded within the iframe that gets dynamically added but with a delay. There is no way I can determine whether the file was literally created or not. Do let me know if I am not very clear or missing something.

    Thanks,
    Girish

    1. Yeah there isn’t a way really for file downloads short of writing a cookie that contains the information you want the client to know about (basically the same way jQuery File Download works). You could write a cookie that contains that information and look for it in the client if that makes sense.

      1. Hello again,

        Yes, no easy way to send the data back. Was wondering if we can send a response back along with url after successful download. Will try and see how can this be done without much changes to the code.

        Thanks,
        Girish

      2. Hello John,

        Info – Might help others looking for a solution. Worked well for me though.

        After trying various ways to pass in data back from servlet, I stuck to basics – followed what the plugin does. Use one cookie to pass values like conxerr, nodata, true, false etc.

        While using IE11 for testing, the condition was always true and setTimeout kept looping for the code below.

        if ($contents.length && $contents[0] === $form[0]) {
        isFailure = false;
        }

        Changed the above code to


        if ($contents.length && $contents[0] === $form[0]) {
        if(document.cookie === "fileDownload=nodata"
        && document.cookie === "fileDownload=conxerr"
        && document.cookie === "fileDownload=false"{

        isFailure = false;
        }
        else {
        isFailure = false;
        }
        }

        I introduced a condition to check the cookie being returned from the servlet for conxerr, nodata and false (any other error that is not caught) and called internalCallbacks.Fail accordingly.

        Also Changed


        if (isFailure) {
        // IE 8-10 don't always have the full content available right away, they need a litle bit to finish
        setTimeout(function () {
        internalCallbacks.onFail(formDoc.body.innerHTML, fileUrl);
        cleanUp(true);
        }, 100);

        return;
        }

        TO


        if (isFailure) {
        // IE 8-10 don't always have the full content available right away, they need a litle bit to finish
        setTimeout(function () {
        if(BrowserDetect.browser == 'Explorer') {
        internalCallbacks.onFail(document.cookie, fileUrl);
        }
        else {
        internalCallbacks.onFail(formDoc.body.textContent, fileUrl);
        }
        cleanUp(true);
        }, 100);

        return;
        }

        If these error codes were true, send back the cookie itself else send formDoc.body.textcontent. This would contain the JSON data received from the servlet.

        Handled the case based on what responeHtml would have in the script.

        NOTE: I took the Browser detection code from Stackoverflow –

        Hope this is helpful. Thanks for your pointers John.

        Thanks,
        Girish

  114. Hi John, thanks for this great blog, beside a great plugin, this explained well why ajax request cannot download file, is this means we can not have this plugin work with WebApiContrib.Formatting.Xlsx?

    The (WebApiContrib.Formatting.Xlsx]) doesn’t need to save an file on server side(which I like most), but it needs a content-type:application/vnd.ms-excel set in header, is there anyway we could work out a solution that can work with it?

  115. I’m using DoddleReports to build and download excel reports in our MVC project. The obvious issue is triggering the “thinking” animation when the excel sheet is finished rendering, hence, I was hoping jquery.fileDownload.js would work for our situation. I have no issues downloading the excel sheet using this plugin, but for some reason the successCallback never gets triggered. Any thoughts on why that would be? Here’s my call:

    $.fileDownload($that.options.report_export_url + “?id=” + JSON.stringify(parms, null, 2),
    {
    successCallback: function (url){ alert(“Excel is finished.”); }
    });

    The “report_export_url” is a call to a controller action (ie: /Reports/Export/ExportData.xlsx), where DoddleReports takes over and spits out the excel file to the browser. Any thoughts on why the successCallback isn’t getting called would be appreciated. Thanks.

  116. He navegación en línea mayor que tres actualidad ,
    pero yo de ninguna manera descubierto llame la atención artículo como el tuyo .
    Es bastante pena suficiente para mí . En mi opinión , propietarios del sitio bueno materiales contenidos como
    lo hiciste , el Internet puede ser mucho más útil útil que nunca.

    \

  117. Hi John,

    This plugin is very useful. Unfortunately, using it with a POST request (as in the 3rd example on the demo page) does not appear to work in Internet Explorer 11 or higher. It returns the follow error:

    SCRIPT70: Permission denied
    File: jqueryfiledownload.apphb.com, Line: 4, Column: 10345

    I’m not sure what the underlying issue might be, but I’m just checking to see if anyone knows of a workaround to get this to work in newer versions of Internet Explorer.

    Thanks,
    Reid

  118. Hey John, Great plugin! Really useful. Hey I was wondering about renaming the files programmatically client-side (because I change their names on the server to prevent conflicts). I was wondering if you have any suggestions on how to do this/ if this is already in the API and I overlooked it? Thanks for the help!

  119. Hey,

    this is great stuff, thanks for doing it!

    My question is how could I do custom action depending on server response? Use case: depending on the file size, I will either provide a download right away or send them an email with the file. In the latter case, I want to redirect them to a page explaining they will get an email (or show a different message than if the download happened right away. Without redirecting…). How could I achieve that with this awesome plugin?

    Žan

  120. Hello,
    I’m using your great piece of code on a site of mine. It woks greatly but I don’t understand wether I should include support/ javascript files (gritter, shBrushScript, shBrushXml and shCore) because to me it seems not to be any reference among these files and fileDownload… could you make it clear if they are needed?

  121. Hi there,

    Wow! This is just what I’m looking for. But what I don’t understand (sorry still working on becoming the developer I want to be) is where and how to put the Cookie code and what to do with this iFrame mentioned in this tutorial.

    Hope you can help me with that.
    Thanks in advance

  122. 1st problem is I am unable to download pdf file and images in explorer
    2nd problem is its not working in in chrome browser
    kindly help me asap
    thanx in advance

  123. Hi John,

    I am using your plug-in and it works like a charm. However, I am facing an issue. Hope you could point me in a write direction to fix it. Most of the time the plug-in works fine, but sometimes it just closes the progress dialog box without giving any file to download. On further digging, I found out that while writing the file to response object it throws following

    but sometimes it throws following exception:

    The remote host closed the connection. The error code is 0x800703E3.
    TARGETSITE: Void RaiseCommunicationError(Int32, Boolean)
    STACKTRACE: at System.Web.Hosting.IIS7WorkerRequest.RaiseCommunicationError(Int32 result, Boolean throwOnDisconnect)
    at System.Web.Hosting.IIS7WorkerRequest.ExplicitFlush()
    at System.Web.HttpResponse.Flush(Boolean finalFlush, Boolean async)
    at System.Web.HttpResponse.Flush()

    There seems to be couple of reasons for this as suggested in some forums, user navigates to some other page or closes the browser.

    In my case none of the above reasons is true.

    Please advise me on the best way forward.

    Thank you.

    Regards,
    Gaurav

  124. successCallback and failCallback not works

    $.fileDownload($(this).prop('action'), {
    preparingMessageHtml: "We are preparing your report, please wait...",
    failMessageHtml: "There was a problem generating your report, please try again.",
    httpMethod: "POST",
    data: $(this).serialize()
    successCallback: function(url) {
    $preparingFileModal.dialog('close');
    console.log('RELOAD');
    location.reload();
    },
    failCallback: function(responseHtml, url) {
    $preparingFileModal.dialog('close');
    $("#error-modal").dialog({ modal: true });
    }
    });

    1. Hi Xavier, may I know the successCallback and failCallback not works issue whether has fixed? I’ve met the same problem to you.

      Here is my code:
      $.fileDownload(proposalUrl, {
      successCallback: function (url) {
      alert(1);
      },
      failCallback: function (html, url) {
      alert(2);
      }
      });

      May I get any advise from you? Thanks a lot in advance.

    2. Issue has fixed, just add below code in java action is work.

      response.setHeader(“Set-Cookie”, “fileDownload=true; path=/”);

  125. Looks very promising !
    Nevertheless I’m trying to use it in a special scenario, and I’m not sure it’s even possible to achieve to use it the following way :

    I would like to rely on your code to handle data that have already been downloaded !
    Actually, I’m using a client control that performs xhr post callbacks with it’s very own post variables.
    I would like to perform the same post request as the control but with additional variable, but the control does not allow it easily…
    The best I can do, is use the control to generate a callback with my additional variables…

    But then, I have the HTTP response containing the downloaded file, that I would like to pass to $.fileDownload !

    Is there a way I could use your library just to reuse the presentation mechanism of downloading/downloaded data with data I actually download by my side ?

    Thanks, be blessed
    j.-p.

  126. Hi John, thanks for a great plugin, and great explanation of what is happening under the hood. I am trying to implement your plugin in ASP.NET Web API controller and have a question. How should I call the server to be able to get a feedback that could be displayed to the user. I use GET request:

    $.fileDownload(“url here (GET)”)
    .done(function () {
    alert(“fine”);
    })
    .fail(function() {
    alert(“wrong”);
    });

    Unfortunately js code doesn’t wait for the server method to be executed, and done() function gets triggered straight away, before file gets downloaded. In case of any issues server side, fail() function never gets triggered at all!

    My server method looks like so:

    public HttpResponseMessage GetExport([FromUri]MyObject object)
    {
    HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
    response.Content = _service.CreateStreamContent;
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue(“attachment”)
    {
    FileName = object.Title + “.xls”
    };
    HttpContext.Current.Response.SetCookie(new HttpCookie(“fileDownload”, “true”) { Path = “/” });
    return response;
    }

    Hope you’ll find some time to look at my issue.

    Thanks in advance,

    Bartosz

  127. Any way to change content type? Tried setting it like this: “contentType: ‘application/json'” but the request header on my express server still says the content-Type is application/x-www-form-urlencoded.

  128. Hello!

    Fantastic work, the library is pretty solid in 2016.

    While retesting use cases with mobile devices using the test page I noticed this small bug on IOS (not tested on android). If you use the promise scenario, the “alert” in fail prevent the automatic close of the tab, you need to close the tab manually to see the alert. If you comment out the alert, the tab close by itself (which would be the prefered scenario as tab opening is a little bit intrusive).

  129. Hi John, Excellent plugin. I am trying to pass $form.serialize() while calling $.fileDownload() as a param. This code works fine in Chrome and does not work with IE. Can you please suggest a way to pass the form data that is compatible in both IE and Chrome. Thanks in advance.

  130. Hello John I am facing an issue with the plugin. It works fine for FF and IE. But for the Chrome it always ends up instantly in the successCallback. Here is the code that I use:
    filterUtils.dialogueControl(true, "pleaseWaitWindow", "Calculating the relations...");
    $.fileDownload(configData.GetMapData, {
    successCallback: function (url, some, some2) {

    filterUtils.dialogueControl(false, "pleaseWaitWindow", "Calculating the relations");
    },
    failCallback: function (responseHtml, url) {

    //filterUtils.dialogueControl(false, "pleaseWaitWindow", "Calculating the relations");
    },
    httpMethod: "POST",
    data: {object: JSON.stringify(tmpEdges)}
    });
    //return false;

    What is interesting, return false statement has no effect in any case. Do you have any idea what might be making this issue? I would really like to avoid setting a special case for Chrome and adding a timeout or similar hack solutions.

    Thank you for your great plugin.

  131. Hi,

    We are using plugin for downloading the files.
    using
    $.fileDownload(response);

    response is file path.

    Downloading is working fine for Mozilla , Chrome with capital extension for example PNG,GIF.

    But files with captial extension (PNG,GIF) is not working on IE.

    Please suggest

  132. Thank you for this plugin, I managed to overcome my problem in .NET for which I spent 3 days now (March 2016) battling with iframes and onload events to download a ZIP file! I just couldn’t get the right response out of my iframe, plus there was a spinning animation I had to signal to start and stop so that it indicates when the download is still in progress. Your plugin worked, I had to set the cookie too! Thank you!

  133. Hi John,

    I am using file download to download .xls file from server but after downloading the file when i am doing save as it’s showing XML file instead of Microsoft Excel in save as type.

    Can u plz help me out in this,how to show Microsoft Excel as default save as type when do save as for the downloaded .xls file?

  134. Hi John,

    Great Utility.

    For me it’s working fine in all browsers except in IE 11, that also in case of failure only, in below code i am getting responseHtml as blank string(“”). For other browsers i am getting proper error message coming from server. Please help.

    UI Code:
    $.fileDownload($form.prop(‘action’), {
    httpMethod: “POST”,
    data: $form.serialize(),
    successCallback: function(url) {
    $(“#myspecialform”).remove();
    App.MsgBox.ConfirmDialog([“contentpack:messages.cp_export_success”],undefined,undefined,
    that.navigateToListPage,undefined,true);
    },
    failCallback: function(responseHtml, url, error) {
    $(“#myspecialform”).remove();
    if(App.getBrowser().name === “IE”){
    //TODO: display generic error msg as responseHtml is blank
    } else{
    responseText = that.removeHTMLTag(responseHtml);
    App.MsgBox.showErrorMsg(responseText,undefined,false);
    }

    }
    });

    Server Code:
    outPutResponse= Response
    .ok(stream, MediaType.APPLICATION_OCTET_STREAM).type(“application/zip”)
    .header(“content-disposition”,”attachment; filename =\”” +fileName+ “.zip\””)
    .header(“Set-Cookie”, “fileDownload=true; path=/”).build();
    return outPutResponse;

  135. Good writing – In case , if anybody is wanting to merge PDF or PNG files , my husband discovered announcement here “https://kdp.amazon.com/community/profile.jspa?userID=806143”

  136. What do I need to do to implement authorisation headers? I mean something like this:

    beforeSend: function (xhr) {
    var token = authToken;
    xhr.setRequestHeader(“Authorization”, “Bearer ” + token);
    }

    Because my server is protected by JWT.

  137. Hello

    It is not working for me in iOS 8
    i am using this code

    $.fileDownload(‘http://localhost:2410/GenerateFile.aspx?region=7’)
    .done(function () { alert(‘File download a success!’); })
    .fail(function () { alert(‘File download failed!’); });

    generateFile.aspx Code behind

    protected void Page_Load(object sender, EventArgs e)
    {
    int ID = this.ID; // Convert.ToInt16(Request.QueryString[“Region”]);
    PDF pdf = new PDF();
    Plan plan = Plan.SelectRecords(Base.RecordType.SelectByID, ID).FirstOrDefault();
    PdfDocument doc = new PdfDocument();
    doc = pdf.Report(ID, Server.MapPath(“~/uploadedimages”), Server.MapPath(“~/images”), Server.MapPath(“~/temp”));
    Session[“File”] = doc;
    Response.Write(string.Format(“parent.RequestCompleted(); document.location = ‘RetrieveFile.aspx?region={0}’;”, ID.ToString()));
    }

    what can be the issue? can you please help me in this
    Thanks

  138. Hi John,
    I’ve been using this plugin for some months and it has worked fine so far. Unfortunately in the last couple of days I had some problems with very large files (over 2 GB). Is this a limit of the plugin or what can I do to make it support larger files?
    Just some more info you may need: web application uses java 7, runs on tomcat 7 and the file is a zip built dinamically starting from files in a given directory. I noticed the zip had a size according to log of 2147483647 bytes which is the max integer value in Java (even though fileLength field is defined as long in my class), the real size of the zip was in fact some MB more than that, so I guess its value was cut due to some hidden conversion from long to int.

    Can you suggest any way to avoid this problem? because so far plugin worked very well and I certainly wouldn’t want to find another solution based on something else.

    Thanks in advance

    1. I am about to move forward with the jquery.FileDownload plugin and am anticipating larger files on our production site. Did you find a workaround/fix for this?

  139. John,

    I recently fixed a bug in our web app that required me changing your code.
    When abort() is called and the browser is Internet Explorer the file still downloads to the browser.
    The fix is to set the iframe src attribute to “” before remove() is called.


    var promise = deferred.promise();
    promise.abort = function() {
    cleanUp();
    $iframe.attr("src", "");
    $iframe.remove();
    };
    return promise;

    It would be nice if you include this in your code base for the benefit of others and in case our team upgrades our version of your code one day.

    Sincerely Joe Kahl

  140. Hi there, the basic settings appear to working fine for me locally, but when I move this onto my UAT server, the file I want is downloading, but i’m not being presented with the Save As dialog.

    If a run F12 I can see the file in the response.

  141. Hi, I want to implement jquery.fileDownload.js in my ASP.NET Webform project. I am trying for last few days but it is not working. IF any body has done it before, please share sample code. Thanks in Advance.

  142. Hi. I’m using your library for downloading files via jQuery:


    $("#report_pdf_download").click(function(){
    $.spin(true);
    $.fileDownload("{{ path('report_indice_pdf') }}", {
    successCallback: function(url) {
    $.spin(false);
    },
    failCallback: function(responseHtml, url) {
    alert("Errore nella generazione del file PDF!");
    $.spin(false);
    }
    });
    });

    How can I set a timeout to the call? Thank you.

  143. Hi, I am receiving next exception when trying to download a big csv file from my instance
    `DOMException: Blocked a frame with origin “” from accessing a cross-origin frame.
    at getiframeDocument (…/jquery.fileDownload.js:423:27)
    at checkFileDownloadComplete (…/jquery.fileDownload.js:370:78)`

    Any ideas how to solve it?

  144. Thank you for sharing your work.

    Is it possible to use this for multiple links on a same page? will an empty form open for each link?

  145. I got this working on my local machine (Win 7 using ASP.NET MVC 5 in IIS) but the dialog doesn’t close when I move my code to our development server (IIS on Win 2012 server). I can see in the Internet Explorer F12 developer tool that I am indeed returning the required cookie. I am using your attribute code to decorate my controller method. I’m using FileDownload v1.4.4. Any ideas?

    1. I just realized my server is using HTTPS and the HTTPOnly flag is set on the cookie, making it inaccessible by your script. Any workarounds other than disabling this flag for all my cookies?

  146. Hi John,

    This cookie that is being set fileDownload=true;, should this also have the httpOnly parameter?

    Siddharth

  147. Hi

    I have to add Security headers like “X-XSS-Protection” in FileDownLoad.js. Is there a way so that I can do this in ASP.NET Application.

  148. FYI: The failCallback will be triggered if you send back content type “text/html” but not if you use “application/xhtml+xml” as it won’t detect the tag in your response (at least in Chrome).

Leave a Reply

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

Proudly powered by WordPress | Theme: Cute Blog by Crimson Themes.