I’ve been neglecting jquery.fileDownload.js a little bit while working on my Durandal.js and FluentKnockoutHelpers demo but since that’s mostly wrapped up I have merged some pulls and added promise support to jQuery File Download. Promises make using the plugin a whole lot cleaner. If you haven’t used them yet start to they are awesome! Enjoy!
As usual the source can be obtained here:
https://github.com/johnculviner/jquery.fileDownload
A short example of what you can now do:
$.fileDownload('some/file/url') .done(function () { alert('File download a success!'); }) .fail(function () { alert('File download failed!'); });
Hi John!
I’m trying to use your plugin for download dynamically generated pdf from server, but I’m getting error: “Uncaught TypeError: Cannot read property ‘undefined’ of undefined”. Code snippet:
$.fileDownload('Trips/AsyncPrint', {
successCallback: function (url) {
alert('done!');
},
failCallback: function (responseHtml, url) {
alert('fail.');
},
httpMethod: "POST",
data: JSON.stringify(d)
});
What’s wrong? Thanks for reply and have a nice day… 🙂
How we can implement with PHP? Where i need to specify the headers? Please help.
Hi John,
This plugin has been very useful for me, I just had an issue trying to send a parameter when the symbol “=” is present in some field value as the value is not been send complete in the request, to solve this, I just replaced the logic to parse the URL attributes to send those as hidden elements in the form for a POST method. This was my change:
var search = /([^&=]+)=?([^&]*)/g;
var match = null,
key = null,
value = null;
while (match = search.exec(settings.data)) {
key = match[1]
if (key) {
value = settings.encodeHTMLEntities ? htmlSpecialCharsEntityEncode(decodeURIComponent(match[2])) : decodeURIComponent(match[2]);
formInnerHtml += "";
}
}
Please, let me know what do you think about it?
Gabo
Hi Gabo,
Could I get a complete copy of your script?
Thanks,
Chris
How can I use this on my asp.net webforms project? Can you please post some codes on how to use this in webforms. thanks
I have problem.
I have such code
$(function()
{
$(document).on(“click”, “a.download”, function()
{
$.fileDownload($(this).prop(‘href’))
.done(function() { alert(‘File download a success!’); })
.fail(function() { alert(‘File download failed!’); });
return false;
});
});
but File download a success! has neved appeared. File is downloaded but successCallback (.done) does no trigger. any ideas?
You may need to try and add $.proxy from Jquery. I had to use it recently for a project. It stems from how Javascript handles scopes.
.done $.proxy(function(args) {
doStuff();
}, this)}
Something like that may work, I have not tested it.
I had the same problem and is was all about the cookie that you have to write when serving the file. There is a note in every page but I also “jumped” over it. *^_^*
That’s the solution.
I would like to suggest that when you hide the iframe in your plugin, instead of doing .hide() or display:none, you should do position:absolute;top:-10000px; or the like. This is because if the iframe has js code that runs when the page loads that tries to manipulate the DOM it will fail if the frame is hidden. BTW, this is the case especially in IE.
I am attempting to use your plugin to allow users to download jpeg files. The code works without generating an error, however, it also does NOT initiate the download process. Because the content can be rendered by the browser, it simply is rendered (yet kept invisible) in the iframe.
I am at a loss with this situation. I’ve been working on this problem for some time. Your assistance is greatly appreciated.
Thanks,
– John.
Are you setting Content-Disposition: attachment;filename=(file)?
If so, have you tried also plugging in a bogus MIME type to prevent the browser from realizing it’s an image?
Gabo I would be interested in a complete copy of your script if you’re still reading this.
Thanks,
Chris
I have the same problem of Roger.
File is downloaded but successCallback (.done) does no trigger. any ideas?
Thanks
+1
I can not make it work in asp.net webforms. Can you upload an example?
Hello
is there any crossdomain configuration to setup on the server where the files are hosted ? i’m trying your script and it’s working if i set 1 of your example files as target, but i get an “error occured” when trying with a pdf hosted on my server (yes, i double checked the file url to make sure it is the good one).
any thoughts ?
thank you for your help
Cross domain doesn’t work unfortunately because of security restrictions placed on cookies and iframes across domains
hey…john
i am not able to implement this plugin in my mvc4 site. i want to show waiting dialog for my diff excel file’s download period.
can you tell me exact steps for that??
please?
The plugin is great,
One problem though, if the cookie was not set and you try to download the file, the function checkFileDownloadComplete() { … } will get into the infinite loop and failCallback doesn’t get called. You can replicate it by putting console.log(‘something’) at the beginning of the function. Tested on Chrome and FF.
Roman,
So you are saying it’s not working for you on the Demo site?
John,
It works, actually. It works in my tests as well. If attachment is there the cookie gets set and download is initiated. If the attachment is not there, the cookie is not set and download is not initiated and I’m not redirected 🙂 but, checkFileDownloadComplete keeps spinning in setInterval.
Wow, embarrassing 🙂 it was my mistake on the server. It was returning internal server error AND the attachment header messing up the browser. It works great.
Thank you.
No problem!
Hello John,
I’m getting the following error:
Resource interpreted as Document but transferred with MIME type image/png
Same error with all file types. I tried some code modifications on my site but nothing works.
Can you help me please?
Kind regards!
hey , when i press downlaod when it been succed not working hide the tab, the tab not hidding ! why?
Hi John,
Excellent plugin, i’ve got the following code working to download files and it successfully displays error if file not found and displays the please wait while we prepare your file message. However, when the file download begins, the message should disappear like it does on your demo but its not disappearing in my code below. Any ideas what i’m doing wrong?
$(document).on("click", "a.fileDownloadSimpleRichExperience", function () {
$.fileDownload($(this).prop('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!
});
download
Are you adding a cookie as required?
Thanks for your reply John, didnt see anything about adding a cookie. At what point do I add the cookie? and what cookie? you got any examples?
I’ve added note of this to the source now too.
https://github.com/johnculviner/jquery.fileDownload
also mentions it.
I’ve put the line:
document.cookie = settings.cookieName + “=true; path=” + settings.cookiePath;
last in the onPrepare-function.
By that I did not need to have it set by code.
onPrepare: function (url) {
//wire up a jquery dialog to display the preparing message if specified
if (settings.preparingMessageHtml) {
$preparingDialog = $("").html(settings.preparingMessageHtml).dialog(settings.dialogOptions);
} else if (settings.prepareCallback) {
settings.prepareCallback(url);
}
// Set the cookie each time the function is prepared // Klaus
document.cookie = settings.cookieName + "=true; path=" + settings.cookiePath;
}
I think , the code should also check for the cookie in the document of iframe. When I wrote cookie, it wrote in the iframe.document instead of current document. I modified the code to do this:
var cookieDoc = downloadWindow ? downloadWindow.document : getiframeDocument($iframe);
if (cookieDoc.cookie.indexOf(settings.cookieName + “=” + settings.cookieValue) != -1) {
//execute specified callback
internalCallbacks.onSuccess(fileUrl);
//remove the cookie and iframe
cookieDoc.cookie = settings.cookieName + “=; expires=” + new Date(1000).toUTCString() + “; path=” + settings.cookiePath;
cleanUp(false);
return;
}
John,
I am using your library to download some Excel reports, but am having some issues running a long-polling type of progress check. I set up an interval in the prepareCallback to check a progress URL on the server, but it only runs once and doesn’t return until after the download has completed.
Any ideas as to why your iFrame form submission would cause other XMLHTTPRequest’s to block?
Thanks for your help with this.
Interesting issue! Could it be due to this? http://johnculviner.com/asp-net-concurrent-ajax-requests-and-session-state-blocking/
If thats not the case there might be some hidden thing with how iframes work (perhaps different cross browser) that block same origin requests or something. Please let me know what you discover!
Hi John,
i am using the plugin and it is working fine for desktop browsers. but on Mobile browsers [Android and Ios] it is making two calls to server to get the response. both the calls are returning with a downloadable PDF document, but the token is getting expired.
Please let me know if we can restrict it to make only one call from Android and Ios browsers ?
So, I’m researching using your code to invoke a POST of a JSON body to my internal server to push a file to my end user. The problem is, like Sebastian, who I think is trying to do the same thing or similar, that your code doesn’t have the ability to push a JSON body to the server; and probably rightly so. Looking at your code, it seems that you’re “tricking” the client into creating and submitting either an iframe or a new document window to make the call to the server with the form entities within the respective container.
I’m researching more to patch your 1.4.2 script to allow such an ability, if possible. I’m just reaching out to see if you could lend some pointers on whether it’s doable or not.
Thanks!
Hi, great plugin!
Success is working fine, but my fail callback never gets called even though my server response looks the same as on the demo page for failures — except my Content-Type is “text/xml” instead of your “text/html”. Is that it?
$.fileDownload(url, {httpMethod:’POST’, data: {“from”:”jquery.fileDownload”}})
.done(function (url) { $.bootstrapGrowl($(event.target).text() + ” – download successful! “, {“ele”: event.target, “type”:”success”, “width”: “auto”}); })
.fail(function (responseHtml, url) { $.bootstrapGrowl(responseHtml + $(event.target).text() + ” – download failed! “, {“type”:”error”, “width”: “auto”}); });
Thanks!
I changed the response to use Content-Type “xml/html” and the fail callback works. Should have tried that first (arg is “responseHtml” after all) 🙂
i am not able to implement this plugin in my mvc4 website.
i want to display waiting dialog box.
can any one tell me exact steps for this process??
please??
Hi,
I want to get the size of the file before the file gets downloaded. Is it possible?
Thanks in Advance,
Gupta.
Hello, Nice feature!
The callback functions (either using “.done()” or “successCallback” ) in my case never get executed.
I just return a Content-type: application/vnd.ms-excel and Content-Disposition: attachment response and i have this js code:
$.fileDownload(url)
.done(function () { alert(‘success test’); })
.fail(function () { alert(‘fail test’); });
What am i missing?
Thanks.
Its a great plugin and I have easily implemented the success scenario.
But am not able to handle the failure scenario.
In the event of failure, I m setting the cookie as “fileDownload=true; expiry=” on the server, but failCallback is not being invoked.
Is this enough or should I do something else? I m using java for server programming.
Would be very glad on your response.
For those want to use a “JSON” powered file downloader (for example to call a WebMethod on .NET) i’ve changed the file a little bit:
http://www.papersoft.it/jquery-download-con-parametri-json/
Direct JS link: http://www.papersoft.it/wp-content/misc/jQuery.fileDownload.js
I’m sure my changes can be refactored.. but i have no time at moment..
To use json parameters you can use a call like
$.fileDownload("", {
httpMethod: "POST",
data: dataToSendExport,
contentType: "application/json"
})
.fail(function () { alert("Error during export") });
where dataToSendExport is an array of objects built like:
dataToSendExport[0] = { "tableName": tableName };
dataToSendExport[1] = { "columns": replaceAll("\'", "\\'", JSON.stringify(columns)) };
Hope you find it useful
Is it possible to pass headers in jquery Plugin
Beyond cookies, no. It’s not AJAX it’s an IFRAME hack that is the only cross-browser way I’m aware of to do this
Hello John,
First I would like to thank you for the very nice job that you done.
This plugin is the very best extension that I can found for make my application.
I’ve just a problem with the “done” callback : it’s don’t work.
The file is well downloaded but the callback is not taken into consideration.
The “fail” callback is working good.
That’s my code :
$.fileDownload(url).done(function () { alert('File download a success!'); });
I’ve this problem with at least 2 browser : firefox and chrome.
My application really need this callback… do you know how i can solve my problem ??
Many thankz for your help !!
Mickael
Its like you read my mind! Yoou seem to know sso much about this, like you wrote the book inn it or something.
I think that you can do with a few pics to drive the messge home a litte bit,
but other than that, this is excellent blog. An excellent read.
I’ll certainly be back.
I want to try download image file,I try absolute and relative path in my site, but nothing worked
$.fileDownload('http://www.mysite.com/sites/default/files/toy_images/jpeg/toy-image-1419684403_3170.jpeg')
.done(function () { alert('File download a success!'); })
.fail(function () { alert('File download failed!'); });
or
$.fileDownload('/sites/default/files/toy_images/jpeg/toy-image-1419684403_3170.jpeg')
.done(function () { alert('File download a success!'); })
.fail(function () { alert('File download failed!'); });
both of them return FAIL to me,where is the problem?
Hi John
Great work on this it works really well, thanks!
Kind regards
John,
I need to send back up to a few hundred pairs of field values from a user selection.
The limitation of going through $.param() is killing me.
Due to $.param() my model has to be AccountId and DocumentURL, over and over again.
Even when I get code like this:
var request =
[
{
name: "EncryptedAccountId",
value: URLencode("ZuFr1inhsT2gwV8tcYu4dQ==")
},
{
name: "EncryptedUrl",
value: URLencode("fLFA1GLvRljxk91O4tDnZvoJFt4MClhQZl5SVhC9IeTwUXP8P6yZMGS9UIz9PneoGasaENGFHA3D+Xu7xy0SUoCm8a9LNS9GVbRO246vZEfZf+MyIKwghiZsWDwm1LSQpbO8c8b78gFZkjfYsAKTXgh2eFfP+xqrmmgE8J3AsNjC8WzhwfQyZyttBNuCfMQB4PB+whmLy7nCvrOzVa7q7htCqCFVddPLj2rdsGnvlxqhPuzEX/y6XGpwFaomLfOg+2eQXvKJcn6GS33B9BXObgk8YLmDnjKPWEn3Wgneygeef5YhWNlueMXZyFxsXXvmoMFfLXGLuHU=")
},
{
name: "EncryptedAccountId",
value: URLencode("ZuFr1inhsT2gwV8tcYu4dQ==")
},
{
name: "EncryptedUrl",
value: URLencode("fLFA1GLvRljxk91O4tDnZvoJFt4MClhQZl5SVhC9IeTwUXP8P6yZMGS9UIz9PneoGasaENGFHA3D+Xu7xy0SUoCm8a9LNS9GVbRO246vZEfZf+MyIKwghiZsWDwm1LSQpbO8c8b78gFZkjfYsAKTXgh2eFfP+xqrmmgE8J3AsNjC8WzhwfQyZyttBNuCfMQB4PB+whmLy7nCvrOzVa7q7htCqCFVddPLj2rdsGnvlxqhPuzEX/y6XGpwFaomLfOg+2eQXvKJcn6GS33B9BXObgk8YLmDnjKPWEn3Wgneygeef5YhWNlueMXZyFxsXXvmoMFfLXGLuHU=")
},
{
name: "EncryptedAccountId",
value: URLencode("ZuFr1inhsT2gwV8tcYu4dQ==")
},
{
name: "EncryptedUrl",
value: URLencode("fLFA1GLvRljxk91O4tDnZvoJFt4MClhQZl5SVhC9IeTwUXP8P6yZMGS9UIz9PneoGasaENGFHA3D+Xu7xy0SUoCm8a9LNS9GVbRO246vZEfZf+MyIKwghiZsWDwm1LSQpbO8c8b78gFZkjfYsAKTXgh2eFfP+xqrmmgE8J3AsNjC8WzhwfQyZyttBNuCfMQB4PB+whmLy7nCvrOzVa7q7htCqCFVddPLj2rdsGnvlxqhPuzEX/y6XGpwFaomLfOg+2eQXvKJcn6GS33B9BXObgk8YLmDnjKPWEn3Wgneygeef5YhWNlueMXZyFxsXXvmoMFfLXGLuHU=")
}
];
The MVC controller action gets the wrong data submitted.
I am seeing data like the name of the controller and the name of the action and an null Id coming back.
I check the network traffic and the expected results are in the Form Data.
It seems like web technology itself is so disappointing.
I tried using AJAX. AJAX sends complex JSON data perfectly. But AJAX always wants a response and since my use case is to open up a document the AJAX cannot be used because the byte stream goes to AJAX instead of the browser.
So I tried the fileDownload but I cannot get the user selected data passed back to the controller. Nothing but heart ache!
Can you provide any guidance or suggestions or a demo of sending several pairs of values to the server through the fileDownload to a controller action? I use ASP.NET MVC 4.
[HttpPost]
public FileResult MergeDocuments(Dictionary mergeRequest)
Thanks, Joe
Hey Joe,
Yeah you can’t use “real” AJAX. Not sure, it would be into the specifics of how the model binder is working which I haven’t looked at in a loooong time 🙂
John
Hi, I want to subscribe for this weblog to get most up-to-date updates, therefore where can i do it please help out.
This is my javascript code
to generate pdf using php dompdf
I want to download the file after creation / on success of ajax
I have written following code
//code—-
$(“#ExportToPdf”).click(function(){
// alert($(“#hidden_content”).html());
var pdfData = $(“#hidden_content”).html();
var billNo = $(“#hidden_content #billNO”).val();
//alert(pdfData);
var billDate = $(“#hidden_content #billdate”).val();
// alert(billNo+””+billDate);
bill_name = billNo+”_”+billDate;
console.log(bill_name);
$.ajax({
type:”POST”,
url:”php/PdfGenerate.php”,
data:”&data=”+pdfData+”&bill_name=”+bill_name,
success:function(data){
console.log(‘”pdf\/bill_’+bill_name+’.pdf”‘);
var path = “pdf/bill_2_2015-03-26.pdf”;
//console.log($.fileDownload(“pdf/bill_”+bill_name+”.pdf”));
$.fileDownload(path,{
contentType: “application/pdf”
})
.done(function () { alert(‘File download a success!’); })
.fail(function () { alert(‘File download failed!’); });
console.log(“pdf has been genrated “);
// console.log(data);
},
error:function(){
alert(‘error’);
}
});
});
file fail to download and show following error on console
Resource interpreted as Document but transferred with MIME type application/pdf: “http://localhost/pathology_app/pdf/bill_2_2015-03-26.pdf”.
please give solution as early as possible
Thanking U!!!
Vishal,
I am also getting the same error. Did you find any solution for this? Thanks
Hi,
Love this plugin, but having an issue with getting the error in the failCallback. Error comes as undefined when I use this in my code:
failCallback: function (responseHtml, url, error) {
console.log(error);
}
I think it’s because the plugin code isn’t passing back the error:
internalCallbacks.onFail(formDoc.body.innerHTML, fileUrl);
Is there any way to get the error passed back in this case in the fail callback, so it can be handled appropriately?
Hello John.
Congratulations for their work!
I’d like sugest that on the callback functions
accept as JSON response from back-end.
Example: .done(function (resultParam){}
Or
let the developer choose
Example: .done(function (resultParam){
//code to part to html here.
//code to part to json here.
}
Some times the server need to send errors messages to client (a real error message not a generic error message).
Hi John!
I’m trying to use your plugin for download dynamically generated file from server!
But my server require custom request header token to accept request!
So I must do it how ?
Thanks for reply and have a nice day…
Hai,
I want to try download image file nothing working reply!!!..
$.fileDownload(“images/images.jpg”)
.done(function () { alert(‘File download a success!’); })
.fail(function () { alert(‘File download failed!’); });
image download not working.,..
$(document).on(“click”, “a.fileDownloadLink”, function () {
$.fileDownload(“../images/images.jpg”)
.done(function () { alert(‘File download a success!’); })
.fail(function () { alert(‘File download failed!’); });
});
ポストをありがとうございましたあなたのサイトと私は話題に興味を持つようになりました。私はあなたのコンテンツが好きで、私は私が私の仕事であなたの言葉を使うことができるかどうかを考えていますか?それはそうなのでしょうか?はい場合は、私と連絡してください。ありがとうございます。すべての
Hi,
Love this plugin, but having an issue with getting the error in the failCallback. Error comes as undefined when I use this in my code:
failCallback: function (responseHtml, url, error) {
console.log(error);
}
I think it’s because the plugin code isn’t passing back the error:
internalCallbacks.onFail(formDoc.body.innerHTML, fileUrl);
Is there any way to get the error passed back in this case in the fail callback, so it can be handled appropriately?
So many questions – and NO ANSWERS
i think i have to get rid of this unsupported stuff 🙁
Could not get the completion callbacks to run.
Both the done callback and the successCallback would not run.
Reduced it back to the simplest case possible running in an asp.net mvc app.
Not sure why it’s not running callbacks. Everything else works Ok. May still use it, can’t find anything better.