This will execute an ajax request which will result in a download without refreshing the page with jQuery
<button id='download'>Download Spreadsheet</button>
<form method='get' action='/export.php?' id='hiddenForm'>
<input type='hidden' name='foo' value='bar' />
<input type='hidden' name='foo2' value='bar2' />
</form>
$(document).on('click', '#download', function (e) {
e.preventDefault();
$('#hiddenForm').submit();
});
Make sure your PHP outputs the correct content type
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
Another Option
Based on this post, there isn't an api available to truly detect the loading of a javascript window object across all different browsers. This method uses a defer callback and postMessage
approach to acommodate most modern browsers.
function defer (callback) {
var channel = new MessageChannel();
channel.port1.onmessage = function (e) {
callback();
};
channel.port2.postMessage(null);
}
var awaitLoad = function (win, cb){
var wasCalled = false;
function unloadListener(){
if (wasCalled)
return;
wasCalled = true;
win.removeEventListener("unload", unloadListener);
win.removeEventListener("pagehide", unloadListener);
// Firefox keeps window event listeners for multiple page loads
defer(function (){
win.document.readyState;
// IE sometimes throws security error if not accessed 2 times
if (win.document.readyState === "loading")
win.addEventListener("load", function loadListener(){
win.removeEventListener("load", loadListener);
cb();
});
else
cb();
});
};
win.addEventListener("unload", unloadListener);
win.addEventListener("pagehide", unloadListener);
// Safari does not support unload
}
w = window.open();
w.location.href="/export.php?data=foo";
awaitLoad(w, function (){
console.log('got it')
});