Skip to content

Instantly share code, notes, and snippets.

@DavidMah
Created August 30, 2012 17:03
Show Gist options
  • Star 72 You must be signed in to star a gist
  • Fork 13 You must be signed in to fork a gist
  • Save DavidMah/3533415 to your computer and use it in GitHub Desktop.
Save DavidMah/3533415 to your computer and use it in GitHub Desktop.
File Download requests using jquery/POST request with psuedo ajax
// Takes a URL, param name, and data string
// Sends to the server.. The server can respond with binary data to download
jQuery.download = function(url, key, data){
// Build a form
var form = $('<form></form>').attr('action', url).attr('method', 'post');
// Add the one key/value
form.append($("<input></input>").attr('type', 'hidden').attr('name', key).attr('value', data));
//send request
form.appendTo('body').submit().remove();
};
# A Tidbit of sinatra code to respond
# Assume url is a set variable
# Assume 'key' is the key of the value used in the javascript
post url do
data = params[:key]
puts request.body.read
headers['Content-Type'] = "application/octet-stream"
body(data)
end
@ransoing
Copy link

This is flippin brilliant. There are numerous questions on StackOverflow concerning how to trigger a file download via a POST request, and all of the answers say it's impossible, and that it must be done by setting the window URL.
You need to show them the truth.

@simonmurdock
Copy link

This works a treat, Thanks!

Copy link

ghost commented Mar 28, 2015

Thanks man, I was looking for days...

@Flixit
Copy link

Flixit commented Oct 6, 2015

This is phenomenal. Thanks for sharing.

@RakeshChouhan
Copy link

Thanks for sharing, it is working.

@aboodmufti
Copy link

Perfect!

@lkuty
Copy link

lkuty commented Jan 5, 2016

Thanks, works perfectly and is simpler than most (all ?) proposed solutions seen on stackoverflow

@rpsirois
Copy link

This is awesome! I added (to the form element) a target="_blank" attribute as well to preserve the requesting page.

@gabbio
Copy link

gabbio commented Apr 22, 2016

Very helpfull. Thanks!

@PallaviKumariJha
Copy link

I am little new to JS. I have been searching for the similar answer for a while. I get a response from server like following:

Content-Disposition:attachment; filename=Agency1.zip
Content-Type: application/octet-stream
Date: 2016 May 5 19:41:32+4m 53s
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked

Now the task is to download this response(a .zip file) on User's local system without user being redirected to an URL or a prompt asking him/her to click a button to download the this zip file. After making an AJAX(POST) request I get a success data. Now I do not know how to proceed.

I tried the solution provided by you. It does not make a call to the URL provided neither does it throw an error. Also, can you tell me how will one handle "on success" and "on error" call back from server response when the solution works. Kindly pardon me if I am being naive here. I am little clueless and new to this :)

@uniquename
Copy link

kudos!

@MauricioTRS
Copy link

function download(url, data){

    var form = $('<form></form>').attr('action', url).attr('method', 'post');

    Object.keys(data).forEach(function(key){
        var value = data[key];

        if(value instanceof Array) {
            value.forEach(function (v) {
                form.append($("<input></input>").attr('type', 'hidden').attr('name', key).attr('value', v));
            });
        } else {
            form.append($("<input></input>").attr('type', 'hidden').attr('name', key).attr('value', value));
        }

    });    

    //send request
    form.appendTo('body').submit().remove();
};

@natan88
Copy link

natan88 commented Jan 7, 2017

I modified the line

var form = $('<form></form>').attr('action', url).attr('method', 'post');
var form = $('<form></form>').attr('action', url).attr('method', 'post').attr('target', '_blank');

I use the angle with socket.io and the way the connection was interrupted, that way it was perfect for my case.

Thanks

@marcozs84
Copy link

Just amazing, thank you very much!

@milesrichardson
Copy link

David Mah!! Long time no speak. :) This is a great trick, just found it on google and used it.

@martinxusz
Copy link

really helps , thanks a ton :)

@Marton6
Copy link

Marton6 commented Jan 14, 2018

awesome, thanks

@codeyash
Copy link

6 years..and still working like magic :)

@jcleroi
Copy link

jcleroi commented Jun 30, 2018

Perfect

@AaronActu
Copy link

AaronActu commented Jun 30, 2018

🥇 Thanks a lot @DavidMah 👍

Even if it's not working for my part 😞

Are the key and data attributes essential if I remove the "input" line (line 8) ? It only redirects me.

function download(url){
    var form = $('<form></form>').attr('action', url).attr('method', 'post').attr('target', '_blank');
    form.appendTo('body').submit().remove();
}

EDIT: Sorry, I think it is my fault. Not sure yet
EDIT2: Okay, My problem is now solved Thanks again 😄

@rgaufman
Copy link

rgaufman commented Jul 4, 2018

Here is a more readable coffeescript version :)

attrs = { action: '/target-path.csv', method: 'post', target: '_blank' }
params = { key1: 'value1', key2: 'value2' }
form = $('<form></form>').attr(k, v) for k, v of attrs
form.append $('<input></input>').attr('type', 'hidden').attr('name', k).attr('value', v) for k, v of params
form.appendTo('body').submit().remove()

@tihoho
Copy link

tihoho commented Aug 9, 2018

Server returned error #400.

@dsenthilkumar95
Copy link

I have more than two files to be downloaded at the page. If I click at one file and click the next one before the first download is completed only second file gets downloaded and first one is failing. Please let me know if someone of you have resolved this issue.

@ProjectLinde37
Copy link

Just found today a very simple solution
window.location.href = 'urltofile';

@tharinduEranga
Copy link

Thanks, man, you saved the day!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment