Giter Club home page Giter Club logo

johnculviner / jquery.filedownload Goto Github PK

View Code? Open in Web Editor NEW
1.1K 1.1K 981.0 215 KB

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.

Home Page: http://johnculviner.com/post/2012/03/22/Ajax-like-feature-rich-file-downloads-with-jQuery-File-Download.aspx

License: MIT License

C# 10.80% CSS 20.64% ASP 0.18% JavaScript 36.52% HTML 31.86%

jquery.filedownload's People

Contributors

arrowgamer avatar crimsonglory avatar djemo avatar doronlh avatar futurfrukt avatar itsadok avatar johnculviner avatar jorupp avatar leodutra avatar leoncs avatar lesliegit avatar loraderon avatar maurizi avatar nikgovorov avatar philipvr avatar rcook avatar slamdunk avatar vaceslav avatar zowiks avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jquery.filedownload's Issues

Download file with headers?

Hi.

Nice work on this plugin!
However, my REST API requires an header to be sent for authentication purposes. Is there any chance to send headers along with the file request?

File download

How to download image file using jquery and ajax with single click on image?

Method POST Input Hidden

Hi,
First great job for this plugin. I use it :)
I have just a problème to use json parameter in post method.

I find a solution : not generate the value of hidden by string concatenation, but i use jquery to set them.

                    var formInnerHtml = "";

                    // TII : 24/05/2013 Affectation des valeurs
                    var tabValue = new Array();
                    // TII : 24/05/2013 Affectation des valeurs

                    if (settings.data !== null) {

                        $.each(settings.data.replace(/\+/g, ' ').split("&"), function() {

                            var kvp = this.split("=");

                            var key = settings.encodeHTMLEntities ? htmlSpecialCharsEntityEncode(decodeURIComponent(kvp[0])) : decodeURIComponent(kvp[0]);
                            if (key) {
                                var value = settings.encodeHTMLEntities ? htmlSpecialCharsEntityEncode(decodeURIComponent(kvp[1])) : decodeURIComponent(kvp[1]);
                                formInnerHtml += '<input type="hidden" name="' + key + '" value="" />';

                                // TII : 24/05/2013 Affectation des valeurs
                                tabValue.push({name: key, value: value});
                                // TII : 24/05/2013 Affectation des valeurs

                            }
                        });
                    }

and ....

                    // TII : 24/05/2013 Affectation des valeurs
                    for (var i = 0; i < tabValue.length; i++) {
                        var obj = tabValue[i];
                        $form.find('input[name="' + obj.name + '"]').val(obj.value);
                    }
                    // TII : 24/05/2013 Affectation des valeurs

                    $form.submit();

Do you think it's the right solution ?

"Permission denied" iframe issue in IE9+ only on failCallback

The fileDownload script works great except when the $.fileDownload() call fails in IE9+. When it fails and the failCallback function is called, I get a "Permission denied" exception. The weird thing is that it works fine in IE9+ on the successCallback and it's referencing the same element in both ($container, in my case).

Here is my code:

function generateSingleReport(elementId) {
var $container = $(elementId);
var data = ...;
setTimeout(function () {
$.fileDownload(relativePath("/Report/GenerateSingleReport"), {
httpMethod: 'POST',
data: $.toDictionary(data),
successCallback: function (url) {
$container.toggle('slow');
},
failCallback: function (responseHtml, url) {
$container.find('.progress').removeClass('active');
$container.find('.bar').addClass('bar-danger');
$container.find('.loading-message').addClass('hide');
$container.find('.error-message').removeClass('hide');
$container.find('form select, #btn-generate-report').removeAttr("disabled");
}
});
}, 1000);
return false;
}

Thanks in advance for any insight.

Fails in IE when document.domain is set

I'm working on a fix for this, but in the meantime, here is the basic idea:

If you try to initiate a download from a document that has set its document.domain, the iframe that is used to download the file must also set its document.domain. This is at least true in IE9; I'm not sure of the full browser range.

I was able to get things working locally by doing something similar to the accepted answer in this SO post:
http://stackoverflow.com/questions/14879192/jquery-iframe-access-denied-in-ie-on-some-pages

Basically, around line 307 of jquery.fileDownload.js, you add:

var frameSrc = 'about:blank';
// If document.domain doesn't match the hostname AND its IE, make sure we set the document.domain of the iframe
if (window.location.hostname !== document.domain && navigator.userAgent.match(/msie/i)) {
    frameSrc = "javascript:document.write(\"<head><script>document.domain=\\\"" + document.domain + "\\\";</script></head><body></body>\")";
}

$iframe = $("<iframe style='display: none' src='" + frameSrc + "'></iframe>").appendTo("body");

I'll see if I can get some time to be more helpful this week, but I wanted to at least get the issue submitted and see if someone wanted to run with it.

Document variables httpMethod, and data

I had to look into the source code to see how data was being passed into the backend, and only then realized i could not PUT -- only GET/POST is supported by forms.

So, it would be helpful if the documentation showed quick examples of these two options.

jQuery conflict

Please add var $ = jQuery.noCoflict() to the top of the script before $.extend() . I had to add it to my copy in order for the plugin to work inside of a WordPress site I'm working on..

jQuery is loaded with no alias in WordPress and a few other CMS's.

"done" function never called

the fileDownload cookie installed with java code:
ResponseBuilder ok = Response.ok(value);
ok.header("Content-Disposition", "attachment; filename="ololo.zip")
.header("Set-Cookie","fileDownload=true; path=/")
.header("Cache-Control", "max-age=60, must-revalidate");
http://snag.gy/97In5.jpg

Implement fileDownload using PHP

Hi @johnculviner i would like to know better how i can use jquery.fileDownload with PHP.
I have a page where i set cookie like this:
setcookie('fileDownload', "true", false, '/');
When i try to use this code:
$.fileDownload(file, {
successCallback: function (url) {
console.log("success")
},
failCallback: function (responseHtml, url) {
console.log("error")
}
});

Maybe i'm making some mistake.
I would like to know if you can provide me a simple php example
Thanks in advance,
Simone

responseHtml from failCallback is empty when using IE 10

Hi,

I'm successfully using your plugin on Chrome and Safari. but I'm having this problem when I use IE. My failCallback returns a JSON from server and I use this JSON to show a custom message for the user. It works very well on all browsers except for IE, where the html returns a empty string. Here's a snippet:

failCallback: function (html, url) {
    console.log('html: ' + JSON.stringify(html));
 }

Then I got this output on IE console:

LOG: html: ""

Any thoughts?

UPDATE:

changed the title because it is happening even in IE 10.. When I use the network profiler, the server correctly responds with a JSON but the component is not able to show it.

Usage with a web service that returns JSON or a file

I have a peculiar situation. I use fileDownload for ajax file downloads basically. My backend returns either the file being requested, a 403 html error or a JSON string of errors. The 403 is extremely rare and isn't really an issue but the JSON handling is.

$.fileDownload(query, {
    successCallback: function (url) {
        debug("success" + url);
        alert("ok");
    },
    failCallback: function (responseHtml, url) {
        debug("fail " + url);
        debug(responseHtml);
        alert("fail");
    }
});

All browsers give me the fail alert, but:
with Chrome, responseHtml is:
<pre style="word-wrap: break-word; white-space: pre-wrap;">
{"success":false,"data":null,"errors":["..."],"errorCode":0}
</pre>
With Firefox it's the same but a simple pre without the attributes.
With IE9, the browser prompts the user to download a file that contains the JSON result without a pre wrapper.

Any ideas for a workaround or an alternate way to download?

Passing data as an array

I am using POST Request.

My server expects the input to be a valid JSON as: "keys":["key1","key2"].

Could you please let me know how can I achieve this?

Thanks

Can't download a file twice :(

Thank you for the script. The first download works fine, but if I use the download button again (without refreshing the page), the GUI works fine, but no file is delivered. After page refresh, I can download the file again, but only once. Do you hab an idea?

Best, Christian

Passing information from server to client via cookie?

I got an idea how to pass failure messages from server to client, please comment if this is a possible feature for fileDownload!

In serverside, when my download handler fails, I write a cookie with a failure message like so (ASP.net C#)

Response.SetCookie(new System.Web.HttpCookie("failureReason", Messages.FileNotFound) { Path = "/" });

Then in fileDownload.js checkFileComplete() I added a check to see if failureReason was set

var failreasonIndex = document.cookie.indexOf("failureReason");
var failReason = undefined;
if (failreasonIndex != -1) {
    var i, x, y, ARRcookies = document.cookie.split(";");
    for (i = 0; i < ARRcookies.length; i++) {
        x = ARRcookies[i].substr(0, ARRcookies[i].indexOf("="));
        y = ARRcookies[i].substr(ARRcookies[i].indexOf("=") + 1);
        x = x.replace(/^\s+|\s+$/g, "");
        if (x === "failureReason") {
            failReason = unescape(y);
        }
    }
}

And then everywhere I found I added the failreason variable; for example

internalCallbacks.onFail(formDoc.body.innerHTML, fileUrl, failReason);
settings.failCallback(responseHtml, url, failReason);

Then in the usage side I did the following and it worked just fine!

$.fileDownload('/Print', {
    successCallback: function (url) {
        //...
    },
    failCallback: function (responseHtml, url) {
        debug(responseHtml);
                ///...

I got the debug message at least in IE9 64bit. Is it possible to implement this in the filedownload core? This way of passing messages seems to work quite well, did I miss something? Would this kind of approach work generally for fileDownload? Any caveats or browser support issues I didn't catch?

The only issue so far is that the cookie data for some reason was not unicode, so I couldn't get "ä,ö" working but I suspect that's just some newbie error from me.

Does the failCallback responseHtml work in IE9?

Greetings. I might be doing something wrong again, but I'm trying to pass error messages in the responseHtml. In Chrome I get responseHtml as expected but in IE9 i don't get anything.

My Backend

private ActionResult ErrorMessage(string msg)
{
    return View("ErrorMessage", model: msg);
}

[HttpPost]
public ActionResult Print()
{
    // snip
    if (item == null)
    {
        return ErrorMessage(Messages.ItemNotFound);
    }
    /// snip
}

My frontend

$.fileDownload('/JsFileDownload/Print', {
    successCallback: function (url) {
        debug("ok");
    },
    failCallback: function (responseHtml, url) {
        debug(responseHtml);
    },
    httpMethod: "POST",
    data: $('#PublishForm').serialize()
});

failCallback not invoked in latest Chrome and Safari

Hi, thanks for your helpful plugin. Unfortunately, the failCallback is not executed on latest Chrome and Safari browsers (tested on Mac) if the server responds with a HTTP 400 error code. However, the callback is executed in Firefox. Can you think of a quick fix for this?

PHP cookie documentation

Hi,

On your blog you have an exemple for writing cookie in php :
header('Set-Cookie: fileDownload=true');

It could be useful to add the path of the cookie. It took me some time (and most of my hair ^_^ ) to understand that the callback wasn't called due to the lack of path in the cookie declaration.

So
header('Set-Cookie: fileDownload=true');
should become :
header('Set-Cookie: fileDownload=true; path=/');

Anyway , thanks for your plugins , it does a great job !

Download Manager

Hi,

The browser download the files correctly but the download manager plugin can not download the file.

When user have some kind of download manager plugin installed on the client (like free download manager), the download manager plugin can not download the file.

Is there any work around ?!

Regards,
Alireza

Download succeeds without downloading file

When downloading the file, fileDownload returns with success but the user never receives the file.
Issue seems to be that the iframe for the download is being removed prematurely.
I've tested this with version 1.4.1 on Chrome and Firefox.

If I remove the following lines in function cleanUp(), the file is downloaded:

if ($iframe) {
                    $iframe.remove();
                }

However, that leaves iframe elements in the body.
So, instead of doing the above, I set the timeout to 500 ms instead of 0 in function cleanUp(). That seems to have fixed the problem.
I'm interested to hear if there's a better solution.
Thanks

Weird behaviour in Firefox

In Firefox (tested on v14.01 on MacOSX 10.7 and Windows 7), if you set the browser's preferences to always ask you where to download a file, upon file download you get presented with a window asking if you'd like to save or open the file. If you choose to save and then click "OK" the window disappears and nothing happens: the file dialog is not displayed and the file is not downloaded.

Note this behaviour happens on the demo website for jquery.fileDownload (http://jqueryfiledownload.apphb.com/)

Writing Cookie?

This plugin looks very useful. I am having a hard time understanding your documentation however. I tried to get it working by using code from your demo page but with now luck. Then I noticed you have this warning about needing to write a cookie. But I'm not entirely sure how that should be done in this case. I think normally I would do that using ajax + php, but that's not the method here, right? I'd love some help if you have a moment.

Sending JSON as POST data

Hi there,

I'm writing a service that queries a server using pretty complex POST queries (elasticsearch style) that are sent as JSON. I've realised this plugin converts the POST data into a form that then it places on an iframe to begin the download.

The kind of queries i'm making cannot easily be converted to key-value pairs without nesting. Is there a way i can pass JSON data?

Thanks

IFrame not removed after success/failure

I noticed the Iframe was not being removed after the file download succeeded or failed. I was able to replicate this on the demo in both Firefox and Chrome. Looking thru the code I saw this comment before cleanUp is called in the checkFileDownloadComplete function "//remove the cookie and iframe", but cleanUp doesn't do anything since downloadWindow is never set unless using IOS or Android. I think simply adding $iframe.remove() somewhere in cleanup would do the trick.

FileName Donwloading

When I use this plugin, the filename is cut at first space. If I use normal way, as openwindow or URL the filename is okey, Full and as set in response.

There are some way to fix this?

Download box not showing on Chrome 36

I was trying to use the samples listed here to test in some browsers before use the lib, but the download box not appear in chrome 36.
The download itself occurs, the show and hide message box are working properly too, but the download box did not appear. The down bar with current downloads doesn't work too. but if I access: chrome://downloads the file is there.
This is a known issue? Maybe someone has this solved in one of the many pull requests.

Cross-Origin exception in Chrome when the origins are the same.

This one has me stumped.

I have a web app that has a file upload/download area. Files are downloaded in the background via a temporary iFrame element. This is a single-paged AJAX application and the UI is written in Javascript, jQuery and uses the jQuery.FileDownloader.js to manage the iFrame. The application runs over HTTPS and the site and download URL are on the same exact domain. The back-end is a RESTful application. This has worked great for months. Until today.

All of a sudden, when attempting to download a file in Chrome, the browser reports an error of "Blocked a frame with origin https://example.com from accessing a cross-origin frame."

The problem is that the origin of the main site and that of the iframe are the exact same domain. I have ensured that the domains are the same as well as the protocol. Chrome is the only browser that throws up the cross-origin error. IE, Firefox, Opera, Safari... all work as expected. It's only in Chrome and it's only as of today. To make things worse, no updates were made to the browser. It truly is spontaneous. I've also ruled out plugins as the cause by running in Incognito mode, where none are allowed to run by my settings, as well as disabling my anti-virus software. This problem is being exhibited on other computers, in other locations (not on our LAN or subnet), all running Chrome.

And, again, both domains of the parent frame and the embedded iframe are identical. This only happens against the production server which runs over HTTPS. Other non-HTTPS sites (e.g. our dev environment, localhost) don't have the problem. Our SSL is valid. Since this is a single-paged AJAX application, we're trying to avoid popping up another window for the download.

Hopefully, someone can offer some advice. Thanks in advance.

Same file downloaded twice

I have a dynamic form on submit I call the plugin like below
var method = "post"; // Set method to post by default if not specified.
var path = "downloadExcel.obj";
var formDownload = document.createElement("form");
formDownload.setAttribute("method", method);
formDownload.setAttribute("action", path);
formDownload.setAttribute("id", "fileDownloadForm");
var custhiddenField = document.createElement("input");
custhiddenField.setAttribute("type", "hidden");
custhiddenField.setAttribute("name", "customerId");
custhiddenField.setAttribute("value", customerId); // VALUE IS GETTING UPDATED HERE
formDownload.appendChild(custhiddenField);
...............................................................................
//On printing the form here on console I get the updated formDownload
...........................................................................
formDownload.submit =
$.fileDownload($('#fileDownloadForm').prop('action'), {
httpMethod: "POST",
data: $('#fileDownloadForm').serialize(),
preparingMessageHtml: "We are preparing your report, please wait...",
failMessageHtml: "There was a problem generating your report, please try again."
});

Now I am able to download the file first time successfully but when I try to download second time [without refreshing the page], my variable formDownload is having the updated data but when I debug inside jquery.fileDownload [settings.data] still have the old data. Henceforth downloading the file for previous customer again and again

Download fails on IE 10

It works fine before IE 10.
But on IE 10, it will fail at first time of downloading, then be success when retry downloading again.

A problem with the download of a pdf file

Hello everyone and congratulations for the useful plugin!

I have an issue with the download of a pdf file.
I did several tests, I finally summed up in test3.html file contained in the archive that I have submitted, in attachment (I know it is not very good... I packed the entire test environment, in a file archive, so after this, I changed its name to get it accepted by the site. So you must save it locally and then rename it as zip file! in the extracted dir, you will find all I have used in the test.).
PS. in the fileDownload.js file, I changed the return error function, so to obtain more useful information about the error... but so far still have not managed to solve the problem.
My enviroment is Windows XP (SP3), IE8, FF22, Chrome rel 35.0.1916.114 m.
I tried also the jQuery 1.10.2 (in the dir).

Thank you for your valuable help. If I find a solution before your reply, I'll let you know. Again, thank you.
R.A.

test zip
Save and rename to .zip.
SHA1: 1e081701ffb2a8d07eaf9c387514277ec1a5fd4f
MD5: f6fd3fb728c49af918c12ee6a21bf631

Exception instead of failCallback on Chrome when server offline

Enviroment: $.fileDownload v1.4.1, Chrome 27.0.1453.116.
code:

$.fileDownload(url, {
    data: data,
    httpMethod: type,
    successCallback: function () {
    },
    failCallback: function (response) {
    }
});

If the server which url was specified is inaccessible (for example turn off local IIS/Apache) then the plugin will be infinitely waiting for a response and filling the browser's console with tons of errors:
"Blocked a frame with origin 'http://localhost' from accessing a frame with origin 'null'. The frame requesting access has a protocol of "http", the frame being accessed has a protocol of 'data'. Protocols must match."

I believe that the reason of such behavior is this WebKit's bug: https://code.google.com/p/chromium/issues/detail?id=17325

Cookie never gets created using POST; stuck in loop

Your demo site works fine, but it doesn't work on mine.

The problem is that the check against document.cookie.indexOf(...) always returns -1 and so the script never gets into success mode. If I debug(document.cookie) inside checkFileDownloadComplete() I never see the fileDownload cookie get set. I can't for the life of be find where the cookie is generated so I can't find how to debug that!

If I debug on the demo site the cookie works just fine.

If I get a 404 or 500 error the fail callback fires as expected.

Code that fires the post event:
$('#TestDown').click(function () {
$("#PrintingMessage").dialog({ modal: true });
$.fileDownload('/Compilation/Print', {
preparingMessageHtml: "We are preparing your report, please wait...",
failMessageHtml: "There was a problem generating your report, please try again.",
httpMethod: "POST",
data: $('#CompilationPublishForm').serialize()
});
});

FIle download complete hides all iframes on the page

There is a bug that causes all iframes on the page to be hidden when the file download has completed.

                //create a temporary iframe that is used to request the fileUrl as a GET request
                $iframe = $("<iframe>")
                    .hide()
                    .prop("src", fileUrl)
                    .appendTo("body");

This will hide all iframes, which is a problem when using other plugins such as ckeditor which depends on iframes.

To resolve this, an id should be assigned to the iframe being created above to uniquely identify it for use with this plugin.

$iframe = $("<iframe id=\"fileDownload\">")

The same thing should be done a little bit further down the script for the following line:

                    $iframe = $("<iframe id=\"fileDownload\" style='display: none' src='about:blank'></iframe>").appendTo("body");

There may be similar issues for other elements that are being added to the DOM this way such as forms. I have not confirmed this, but the safe thing would be to always add an id to new elements to ensure that other elements of the same type are not affected.

Thanks!

Getting Back Response in Failure Callback

This below code shown in the blog post doesn't work for some reason related to promise callbacks, neither get triggered properly after a successful file download

$.fileDownload('some/file/url')
    .done(function () { alert('File download a success!'); })
    .fail(function () { alert('File download failed!'); });

also successCallback & failCallback both get triggered on a successful file download and neither have the response available, is there any way to do a more traditional jquery ajax call, something like this

$.fileDownload(url, options).then(function(data) {
                console.log("File download a success!" + data);
            }, function(response) {
                 console.log("File download failed!" + response);
            });

Failure-Callback in Chrome not called, when Download failes with 404

Browser: Chrome

When a download fails with statuscode 404 (not found) and the response body is empty, the plugin does not detect the failed download in Chrome.

The issue cannot be reproduced with the demo-website in it's current form, as all failures are statuscode 500.

Cause:
In function "checkFileDownloadComplete" checks for "formDoc.body.innerHTML.length", wich is 0 when the response body is empty.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.