You would think this would be reasonably easy,
but it isn’t. It might be possible to do
it with a raw XMLHttpRequest, and then again, it might not be. The problem we have is that we want the
browser to interpret it as a new page. I
initially attempted to do this with something like the following using JQuery:
$('#target-iframe).load('page.ajax' + requestParams');
where “target-iframe” is, of course, the
contents of an iframe. But I pretty
quickly concluded it was never going to work.
However, I came up with an almost equally simple
method that works very well. It’s not
really AJAX per se, but the difference is imperceptible to the end user. The following short Javascript snippet will
immediately start a download, assuming of course that the target URL returns
the expected download headers.
function initiateFileDownload() {
var requestParams = "/f_download/1";
requestParams += getPageFilters('', '');
$("#target-iframe").attr('src','page.ajax' + requestParams);
}
<iframe id="target-iframe"
name="target-iframe" src="#" style="width:600;height:100;border:0px
solid #fff;display:none"></iframe>
In this case, I absolutely had to do an Ajax
type loader because I was trying to download results from a page that the user
had already filtered down. I could have
replicated the filter code and regenerated the page, but then I have to worry
about keeping the filter logic in synch between my downloader and the actual
page, which is a scenario best avoided.
Here is my PHP download code that would sit somewhere
such that it gets called by “page.ajax”.
ob_clean();
header('Content-Description:
File Transfer');
header('Content-Type:
application/force-download');
header('Content-Disposition:
attachment; filename="'.$filename.'";');
header('Content-Transfer-Encoding:
binary');
header('Expires:
0');
header('Cache-Control:
must-revalidate, post-check=0, pre-check=0');
header('Pragma:
public');
header('Content-Length:
' . strlen($data));
echo $data;
ob_flush();
flush();