Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Download a file by jQuery.Ajax

I have a Struts2 action in the server side for file downloading.

<action name="download" class="com.xxx.DownAction">     <result name="success" type="stream">         <param name="contentType">text/plain</param>         <param name="inputName">imageStream</param>         <param name="contentDisposition">attachment;filename={fileName}</param>         <param name="bufferSize">1024</param>     </result> </action> 

However when I call the action using the jQuery:

$.post(   "/download.action",{     para1:value1,     para2:value2     ....   },function(data){       console.info(data);    } ); 

in Firebug I see the data is retrieved with the Binary stream. I wonder how to open the file downloading window with which the user can save the file locally?

like image 724
hguser Avatar asked Dec 28 '10 10:12

hguser


People also ask

How to download file with jQuery AJAX?

Downloading PDF File on Button Click using jQueryInside the DownloadFile JavaScript function, the URL of the File is passed as parameter to the jQuery AJAX function. Inside the jQuery AJAX function, using the XmlHttpRequest (XHR) call, the PDF file is downloaded as Byte Array (Binary Data).

How do I download a file using JavaScript?

To ask the browser to download a file it can render, use the following header: Content-Disposition: attachment; filename="downloaded. pdf" (you can of course customize the filename as you need).

What is Ajax explain with example?

AJAX allows web pages to be updated asynchronously by exchanging small amounts of data with the server behind the scenes. This means that it is possible to update parts of a web page, without reloading the whole page. Classic web pages, (which do not use AJAX) must reload the entire page if the content should change.


2 Answers

2019 modern browsers update

This is the approach I'd now recommend with a few caveats:

  • A relatively modern browser is required
  • If the file is expected to be very large you should likely do something similar to the original approach (iframe and cookie) because some of the below operations could likely consume system memory at least as large as the file being downloaded and/or other interesting CPU side effects.

fetch('https://jsonplaceholder.typicode.com/todos/1')    .then(resp => resp.blob())    .then(blob => {      const url = window.URL.createObjectURL(blob);      const a = document.createElement('a');      a.style.display = 'none';      a.href = url;      // the filename you want      a.download = 'todo-1.json';      document.body.appendChild(a);      a.click();      window.URL.revokeObjectURL(url);      alert('your file has downloaded!'); // or you know, something with better UX...    })    .catch(() => alert('oh no!'));

2012 Original jQuery/iframe/Cookie based approach

Bluish is completely right about this, you can't do it through Ajax because JavaScript cannot save files directly to a user's computer (out of security concerns). Unfortunately pointing the main window's URL at your file download means you have little control over what the user experience is when a file download occurs.

I created jQuery File Download which allows for an "Ajax like" experience with file downloads complete with OnSuccess and OnFailure callbacks to provide for a better user experience. Take a look at my blog post on the common problem that the plugin solves and some ways to use it and also a demo of jQuery File Download in action. Here is the source

Here is a simple use case demo using the plugin source with promises. The demo page includes many other, 'better UX' examples as well.

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

Depending on what browsers you need to support you may be able to use https://github.com/eligrey/FileSaver.js/ which allows more explicit control than the IFRAME method jQuery File Download uses.

like image 143
John Culviner Avatar answered Oct 09 '22 00:10

John Culviner


Noone posted this @Pekka's solution... so I'll post it. It can help someone.

You don't need to do this through Ajax. Just use

window.location="download.action?para1=value1...." 
like image 22
bluish Avatar answered Oct 09 '22 01:10

bluish