Downloading file using ajax and jquery after submitting form data using ajax HTTP POST in MVC Many a times we find a need to download a file on doing a AJAX POST request. Normally we would just use the Response.Write to write the fileStream to the MVC Output response, as follows. The success callback function is passed the returned data, which will be an XML root element or a text string depending on the MIME type of the response. It is also passed the text status of the response. I need to start download manually when $('a#someID').click; But I cannot use window.href method, since it replaces the current page contents with the file you’re trying to download. Instead I want to open the download in new window/tab. How is this possible? Jan 13, 2018  Downloading files from POST requests is actually a bit more complicated then it could be - here's how to do it. Occasionally I stumble upon the need to download files from POST requests. An example would be generating PDF files, where the PDF content is dependent on the request. (jQuery, Vue, Angular.). And, of course, you can find. Hi there, I'm just trying to download a file generated from PHP with ajax. Even if I set headers PHP and contentType in Ajax parameters, I have still an Download CSV file through ajax post - jQuery Forum.

  1. Jquery Post Json Download File
  2. Jquery Send Post To Download File
  3. Open Download File
  4. Jquery Post Download File Download
  5. Download File Test
  6. Download File Info
  7. Jquery Ajax Post Download File From Server

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.

Example of the above code in action: https://codesandbox.io/s/fetch-based-file-download-0kxod

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.

Demo (of this exact source):

Source here:

Targeting pretty modern browser(s)?

This might be a better solution to your problem https://github.com/eligrey/FileSaver.js/

Requirements

  • jQuery 1.6+

Common questions and answers

  • Q: I need to send in custom headers. How do I do that?
    • Unfortunately since this plugin uses an iframe and not AJAX you cannot send in custom headers. If you really need to do this and are willing to accept a more narrow range of browser support this might be a better solution to your problem https://github.com/eligrey/FileSaver.js/
  • Q: It doesn't work!?
    • Try out the demo and make sure you are doing exactly what it is doing: http://jqueryfiledownload.apphb.com/ If the demo doesn't work in your browser you have defintely found a bug and us know!
    • Due to iframe security restrictions you must serve up the file from the same domain you see in the address bar

Supported and tested browsers

  • Internet Explorer 6+ - Works fine for standard use cases except in < IE9 JavaScript access to the failed response HTML doesn't (and can't) work reliably due to browser iframe constraints.
  • Firefox 11+ - reasonably sure it will work on earlier versions
  • Chrome 17+ - reasonably sure it will work on earlier versions
  • iOS 5.0+ - reasonably sure it will work on earlier versions
  • Android 4.0+ - non-GET requests do not work due to a long-standing bug in the Android browser. This is handled 'gracefully' with a message to the user.

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

Example of writing cookie (MVC):

https://github.com/johnculviner/jquery.fileDownload/blob/master/src/Common/FileDownloadAttribute.cs
The above attribute can be used on any controller action that may return a file download that you would like to use jquery.fileDownload.js with

For more information and documentation please visit:

Or look at the well documented JavaScript source:

Ruby on Rails integration

The jquery_file_download-railsgem integrates jquery.fileDownload.js into the Rails 3.1+ asset pipeline.

PHP integration

Active21 days ago

I have a jquery-based single-page webapp. It communicates with a RESTful web service via AJAX calls.

I'm trying to accomplish the following:

  1. Submit a POST that contains JSON data to a REST url.
  2. If the request specifies a JSON response, then JSON is returned.
  3. If the request specifies a PDF/XLS/etc response, then a downloadable binary is returned.

I have 1 & 2 working now, and the client jquery app displays the returned data in the web page by creating DOM elements based on the JSON data. I also have #3 working from the web-service point of view, meaning it will create and return a binary file if given the correct JSON parameters. But I'm unsure the best way to deal with #3 in the client javascript code.

Is it possible to get a downloadable file back from an ajax call like this? How do I get the browser to download and save the file?

The server responds with the following headers:

Another idea is to generate the PDF and store it on the server and return JSON that includes a URL to the file. Then, issue another call in the ajax success handler to do something like the following:

But doing that means I would need to make more than one call to the server, and my server would need to build downloadable files, store them somewhere, then periodically clean up that storage area.

There must be a simpler way to accomplish this. Ideas?

EDIT: After reviewing the docs for $.ajax, I see that the response dataType can only be one of xml, html, script, json, jsonp, text, so I'm guessing there is no way to directly download a file using an ajax request, unless I embed the binary file in using Data URI scheme as suggested in the @VinayC answer (which is not something I want to do).

So I guess my options are:

  1. Not use ajax and instead submit a form post and embed my JSON data into the form values. Would probably need to mess with hidden iframes and such.

  2. Not use ajax and instead convert my JSON data into a query string to build a standard GET request and set window.location.href to this URL. May need to use event.preventDefault() in my click handler to keep browser from changing from the application URL.

  3. Use my other idea above, but enhanced with suggestions from the @naikus answer. Submit AJAX request with some parameter that lets web-service know this is being called via an ajax call. If the web service is called from an ajax call, simply return JSON with a URL to the generated resource. If the resource is called directly, then return the actual binary file.

The more I think about it, the more I like the last option. This way I can get information back about the request (time to generate, size of file, error messages, etc.) and I can act on that information before starting the download. The downside is extra file management on the server.

Any other ways to accomplish this? Any pros/cons to these methods I should be aware of?

cezar
6,8824 gold badges30 silver badges59 bronze badges
TaurenTauren
14.6k34 gold badges121 silver badges161 bronze badges

14 Answers

letronje's solution only works for very simple pages. document.body.innerHTML += takes the HTML text of the body, appends the iframe HTML, and sets the innerHTML of the page to that string. This will wipe out any event bindings your page has, amongst other things. Create an element and use appendChild instead.

Or using jQuery

What this actually does: perform a post to /create_binary_file.php with the data in the variable postData; if that post completes successfully, add a new iframe to the body of the page. The assumption is that the response from /create_binary_file.php will include a value 'url', which is the URL that the generated PDF/XLS/etc file can be downloaded from. Adding an iframe to the page that references that URL will result in the browser promoting the user to download the file, assuming that the web server has the appropriate mime type configuration.

SamStephensSamStephens
5,0704 gold badges27 silver badges41 bronze badges

I've been playing around with another option that uses blobs. I've managed to get it to download text documents, and I've downloaded PDF's (However they are corrupted).

Using the blob API you will be able to do the following:

This is IE 10+, Chrome 8+, FF 4+. See https://developer.mozilla.org/en-US/docs/Web/API/URL.createObjectURL

It will only download the file in Chrome, Firefox and Opera. This uses a download attribute on the anchor tag to force the browser to download it.

JoshBerkeJoshBerke
56.2k21 gold badges113 silver badges156 bronze badges

I know this kind of old, but I think I have come up with a more elegant solution. I had the exact same problem. The issue I was having with the solutions suggested were that they all required the file being saved on the server, but I did not want to save the files on the server, because it introduced other problems (security: the file could then be accessed by non-authenticated users, cleanup: how and when do you get rid of the files). And like you, my data was complex, nested JSON objects that would be hard to put into a form.

What I did was create two server functions. The first validated the data. If there was an error, it would be returned. If it was not an error, I returned all of the parameters serialized/encoded as a base64 string. Then, on the client, I have a form that has only one hidden input and posts to a second server function. I set the hidden input to the base64 string and submit the format. The second server function decodes/deserializes the parameters and generates the file. The form could submit to a new window or an iframe on the page and the file will open up.

There's a little bit more work involved, and perhaps a little bit more processing, but overall, I felt much better with this solution.

Code is in C#/MVC

on the client

amerskamersk

3cx free license key. There is a simplier way, create a form and post it, this runs the risk of resetting the page if the return mime type is something that a browser would open, but for csv and such it's perfect

Example requires underscore and jquery

For things like html, text and such, make sure the mimetype is some thing like application/octet-stream

php code

aqmaqm

In short, there is no simpler way. You need to make another server request to show PDF file. Al though, there are few alternatives but they are not perfect and won't work on all browsers:

  1. Look at data URI scheme. If binary data is small then you can perhaps use javascript to open window passing data in URI.
  2. Windows/IE only solution would be to have .NET control or FileSystemObject to save the data on local file system and open it from there.
VinayCVinayC
36k5 gold badges46 silver badges60 bronze badges

It is been a while since this question was asked but I had the same challenge and want to share my solution. It uses elements from the other answers but I wasn't able to find it in its entirety. It doesn't use a form or an iframe but it does require a post/get request pair. Instead of saving the file between the requests, it saves the post data. It seems to be both simple and effective.

client

server

Frank RemFrank Rem
2,9951 gold badge20 silver badges32 bronze badges
James McGuiganJames McGuigan
3,6783 gold badges14 silver badges10 bronze badges

Not entirely an answer to the original post, but a quick and dirty solution for posting a json-object to the server and dynamically generating a download.

Client side jQuery:

Android sdk adb download. .and then decoding the json-string at the serverside and setting headers for download (PHP example):

ralftarralftar

I think the best approach is to use a combination, Your second approach seems to be an elegant solution where browsers are involved.

So depending on the how the call is made. (whether its a browser or a web service call) you can use a combination of the two, with sending a URL to the browser and sending raw data to any other web service client.

naikus

Jquery Post Json Download File

naikus
22.2k4 gold badges36 silver badges43 bronze badges

Jquery Send Post To Download File

I have been awake for two days now trying to figure out how to download a file using jquery with ajax call. All the support i got could not help my situation until i try this.

Client Side

Server Side

Good luck.

Open Download File

Otis-iDevOtis-iDev

Another approach instead of saving the file on the server and retrieving it, is to use .NET 4.0+ ObjectCache with a short expiration until the second Action (at which time it can be definitively dumped). The reason that I want to use JQuery Ajax to do the call, is that it is asynchronous. Building my dynamic PDF file takes quite a bit of time, and I display a busy spinner dialog during that time (it also allows other work to be done). The approach of using the data returned in the 'success:' to create a Blob does not work reliably. It depends on the content of the PDF file. It is easily corrupted by data in the response, if it is not completely textual which is all that Ajax can handle.

Wray SmallwoodWray Smallwood

With HTML5, you can just create an anchor and click on it. There is no need to add it to the document as a child.

All done.

If you want to have a special name for the download, just pass it in the download attribute:

rewrittenrewritten
13.6k2 gold badges36 silver badges45 bronze badges

Found it somewhere long time ago and it works perfectly!

Den NikitinDen Nikitin

Jquery Post Download File Download

Content-Disposition attachment seems to work for me:

Download File Test

application/octet-stream

Download File Info

I had something similar happening to me with a JSON, for me on the server side I was setting the header toself.set_header('Content-Type', 'application/json')however when i changed it to:

Jquery Ajax Post Download File From Server

It automatically downloaded it.

Also know that in order for the file to still keep the .json suffix you will need to it on filename header:

Mr-ProgramsMr-Programs

Not the answer you're looking for? Browse other questions tagged javascriptjqueryajaxrest or ask your own question.

Coments are closed
Scroll to top