Ajax File Download … Or Not
Date : 2007 10 08 Category : Design & UsabilityHaving a user download a file through a web page is a fairly common task, which begins with the painful task of finding out the appropriate headers. As if figuring out headers isn’t enough, what happens when you need conditional data to determine the download? The type of data that cannot be placed in the URL. Well, I naturally thought that Ajax could help send the data, and so my path down the wrong trail began.
Given a URL of http://website.com/file/, we want to be able to POST data to the URL so that a download begins without the user leaving the page they are viewing. The reason the URL alone isn’t enough is because the data that gets downloaded is conditional based on the actions the user has taken so far. So we’ll start with a typical Ajax request.
var myAjax = new Ajax.Request( '/file/', { method: 'post', parameters: 'download=top10', onComplete: function(r) { // file starts downloading? } });It should have been obvious before I even wrote the code, but the code above causes absolutely nothing to happen. Sure, all of the proper headers are returned by the request, but all we are left with is a JavaScript variable containing data. And there is no way to force this variable as a download on the user.
A quick Google search for Ajax File Download didn’t help the cause. This path will lead down many branches, of which the primary one suggests using a hidden iframe to force the download. Hours later I was able to force a static file to download, but never one where I tried to dynamically alter the contents of the iframe.
At this point, it was about to be “quit and do something else” time, but then the solution found me. As I was closing up the project, I saw a form tag in the file that was open. Just a simple form tag. So I created a form, threw in some hidden fields for conditional data, and submitted it:
<form id="super_form" method="post" action="/file/"> <input type="hidden" id="download" name="download" /> </form> $('download').value = 'top10'; $('super_form').submit();Amazingly, a download file prompt appeared. And then I felt a bit stupid. In this case, no trickery was needed — just some straightforward HTML and JavaScript. Hopefully, this will save someone else some frustration down the road.
