View Full Version : FYI: Very simple approach to JS-triggered file downloads
Eric24
1 Oct 2009, 6:22 PM
While looking at the various ways to trigger a file download from JS, I came up with the following; a very simple approach that we've tested to on all current browsers on Windows and Mac. Perhaps this method is well-known, but I was not able to find anything like it--everything I found that used a hidden form also required a hidden iframe and event handler to destroy the hidden form and iframe. This method starts off the same way, but does not require the iframe and cleans up after itself immediately.
var form = Ext.DomHelper.append(document.body, {
tag : 'form',
method : 'post',
action : url
});
document.body.appendChild(form);
// add any other form fields you like here
form.submit();
document.body.removeChild(frame);
If anyone has any questions or thoughts on any problems that this may case that we haven't seen, I'm all ears...
Tnx!
Eric
arthurakay
2 Oct 2009, 5:33 AM
Very interesting... actually wish I had thought of this a long time ago. I have some legacy code where the download forms were hard-coded into the HTML page, so I'll give this a shot. Thanks for sharing!
aconran
5 Oct 2009, 6:45 AM
Clever, you should roll this into a simple method like Ext.forceDownload which takes the url and any additional form parameters.
mystix
5 Oct 2009, 8:04 AM
is there a typo in the code snippet?
shouldn't it be
document.body.removeChild(form);
instead? :-?
mschwartz
5 Oct 2009, 8:30 AM
top.location.href=url
works for me.
(url is the url of the script that outputs the file download, or the file itself)
jay@moduscreate.com
5 Oct 2009, 9:13 AM
The only provblem i see with this approach is that sometimes form submissions to create downloads take time, which is why event management with the iframe is required.
For instance, submit a form that requires the server side to generate a binary (PDF/image/zip?), which could take some time.
What happens when you remove the el from the DOM before the server side has time to respond?
Eric24
9 Oct 2009, 12:53 PM
@mystix: Yes, copy/paste error.
@mschwartz: This approach is fine as long as you only need to GET; the hidden form supports POST.
@jgarcia: I specifically tested for that across several browsers/machines, and it works fine regardless of how big the file is or even how long it takes for the download to start. I believe the reason why is that once the submit call has been made, the browser really doesn't care about the form any more. Of course that was the original purpose of the iframe (to keep the form around until the transaction completed), but in the case of a forced download, it's not necessary.
mschwartz
9 Oct 2009, 4:29 PM
@mystix: Yes, copy/paste error.
@mschwartz: This approach is fine as long as you only need to GET; the hidden form supports POST.
@jgarcia: I specifically tested for that across several browsers/machines, and it works fine regardless of how big the file is or even how long it takes for the download to start. I believe the reason why is that once the submit call has been made, the browser really doesn't care about the form any more. Of course that was the original purpose of the iframe (to keep the form around until the transaction completed), but in the case of a forced download, it's not necessary.
You can always Ajax request the URL you need to GET.
Sheep
27 Jan 2010, 10:11 AM
Thx Eric for the trick. ;) =D>
I don't know, if it's still the "good-way to do it".
Here is my sample on how to add form parameters (using children) (as i'm a complete newbie, it took me a little while to figure it). B)
var form = Ext.DomHelper.append(
document.body,
{
tag : 'form',
method : 'post',
action : 'impex.php',
children: [
{tag: 'input', type:'hidden', name: 'action', value: 'export'},
{tag: 'input', type:'hidden', name: 'list', value: Ext.encode(exportlist)} //export list is a simple array
]
}
);
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
Powered by vBulletin® Version 4.1.5 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.