PDA

View Full Version : Force Download?



cesarulo
12 May 2007, 11:52 AM
Hey Community,

I am trying to get the browser to offer me a download dialog for server-side file content in response to a connection that was initiated with an Ext.data.Connection.request().

The server-side code is pretty much the same that was used in an old application. It sends the force-download headers:



header("Content-Type: application-x/force-download");
header("Content-Length: $size");
header("Content-Disposition: attachment; filename=".$filename);
header("Content-transfer-encoding: binary");


and then barfs out the contents of the file in question.

This is working well; so well, indeed, that I can see the contents of my file in the responseText when I debug my connection callback function. The problem is now I don't know what to do with it. Besides, I don't really think storing it there is such a good idea; some of these server-side files could be huge. Is there a way I can, using javascript, force the browser to offer the user a download dialog and just make it relay the server's response directly onto a file on disk?

I guess one easy way out of this would be to, instead of using a Connection, simply put an anchor there: as there's a force-download Content-type being sent, the browser page containing the rich client will remain undisturbed. The problem with this is that there's a number of possible error conditions that could occur in the server side. I already have working code on the server that sends JSON-RPC headers and an informative message if it finds an error rather than attempt to force a download. The client successfully handles this and shows a pretty error message right now. If I put a link there, I lose the possibility of handling these conditions, and yet worse, any such condition that yields anything other than file content will wipe out the rich client and give the user a meaningless page with server gibberish instead. Not acceptable.

Any thoughts on this matter would be very appreciated. Thanks in advance,

Animal
12 May 2007, 12:22 PM
The only way is with an anchor. You can't actually do anything with the recieved text from an XHR. So target the anchor at an iframe.



<a href="http://myserver.com/getTheDocument" target="my_iframe">Get it</a>


The thing to do is to use Content-Type to indicate to the browser what is coming down.

So if there's an error, send



Content-Type:text/html;

<html><head><script type="text/javascript">alert("something bad happened!");
</script><head></html>


And an alert will pop up.

But if there's no error, the browser will ask what to do with the content.

cesarulo
12 May 2007, 12:35 PM
Oh, Animal, thanks so much!

This prompt answer will pretty much make the difference between a very productive day and one gone to waste for me today :)

Cheers,

heidtmare
13 Aug 2007, 11:52 AM
along these same lines,
i have a comboBox with an on('select') that fires off a request.
The response is a set of headers and an xml file i want to open up in the appropriate application( hence the headers ;p ).

How can i make my event handle this correctly?


var exportToC = new Ext.form.ComboBox({
hiddenName:'exportTo',
store: new Ext.data.SimpleStore({
fields: ['text','value'],
data : [['KML','KML_2_1'],['RSS','rss_2']]
}),
displayField:'text',
valueField:'value',
editable: false,
mode: 'local',
triggerAction: 'all',
emptyText:'Export to...',
width:100
});
exportToC.on('select', function(){
exportToC.disable();
tb1.addText(' Exporting, please wait...');
Ext.Ajax.request({
url : './php/dashboard.php' ,
params: {f: 'export', cacheId: responseDetails.cacheId, exportTo: exportToC.getValue()},
method: 'POST',
success: function ( result, request ) {
//window.open(result.responseText); //nope
//document.write(result.responseText); //nope again
//What now?
exportToC.enable();
},
failure: function ( result, request) {
Ext.MessageBox.alert('Failure', result.responseText);
exportToC.enable();
}
});
});

heidtmare
13 Aug 2007, 12:34 PM
here's what i went with

var exportToC = new Ext.form.ComboBox({
hiddenName:'exportTo',
store: new Ext.data.SimpleStore({
fields: ['text','value'],
data : [['KML','KML_2_1']]
}),
displayField:'text',
valueField:'value',
editable: false,
mode: 'local',
triggerAction: 'all',
emptyText:'Export to...',
width:100
});
exportToC.on('select', function(){
window.open('./php/dashboard.php?f=export&cacheId='+responseDetails.cacheId+'&exportTo='+exportToC.getValue(), 'Export Window');
});