0

First off, I understand this is not the best way of forcing a file download, it's hacky and it's horrible, but hey, I just get told what to do!

So I have a WP installation, and I'm trying to leverage using the WP AJAX to download a file.

My form hits an AJAX callback in functions.php, and after doing some bits n pieces, I am hitting this function:

function download_file()
{
    $file = get_template_directory()."/a_pdf_file.pdf";

    if(file_exists($file)) {

        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="'.basename($file).'"');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file));
        ob_clean();
        flush();
        readfile($file);
        exit;
    }
    else
    {
        die('The provided file path is not valid.');
    }
}

The problem is, the buffer is just being spat out in the AJAX response. No file is being downloaded.

Do I need to do something on the AJAX end, in the success callback maybe?

The other options I have tried seem to fail too.

  • header('Location: $file_url'); doesn't work
  • tried all manner of header options, still no difference
  • window.open(url, '_blank') in AJAX callback gets blocked as a popup
  • window.location() opens in same window, not acceptable
Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
Mr Pablo
  • 4,109
  • 8
  • 51
  • 104

1 Answers1

0

Ajax can not directly download a file, instead you need to open it in it's own frame. You can create your own invisible iframe on the fly like this if you use jquery. This is from my code, but getting rid of jquery here should not be that hard.

function downloadUrl(url) {
    var iframe = document.createElement("iframe");
    iframe.src = url;
    $(iframe).hide();
    document.body.appendChild(iframe);
    $(iframe).load(function() {
        //Show error, if call returned an error instead of a file
        var cont = $(iframe).contents().find("body");
        if (cont.text().length != 0)
            alert(cont.text()); 
    });
}
Torge
  • 2,174
  • 1
  • 23
  • 33