1

Is it possible to use WordPress Ajax to download files. I have this function to download the attachment.

function download_attachment()
{
    $file_path = $_POST['filename'];
    $file_mime = $_POST['mime'];
    $data['file_path'] = file_exists($file_path);

    try{
        header('Pragma: public');   // required
        header('Expires: 0');       // no cache
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Last-Modified: '.gmdate ('D, d M Y H:i:s', filemtime ($file_path)).' GMT');
        header('Cache-Control: private',false);
        header('Content-Type: '.$file_mime);
        header('Content-Disposition: attachment; filename="'.basename($file_path).'"');
        header('Content-Transfer-Encoding: binary');
        header('Content-Length: '.filesize($file_path));    // provide file size
        header('Connection: close');
        set_time_limit(0);
        @readfile("$file_path") or die("File not found.");

    }catch(Exception $e)
    {
        $data['error'] = $e->getMessage() ." @ ". $e->getFile() .' - '. $e->getLine();
    }
    }
    echo json_encode($data);
    die();
}

It is hooked to WordPress main function with this function:

    add_action('wp_ajax_download_attachment','download_attachment');

And the jQuery code is this:

var data = {
        'function': 'download_attachment',
        'filename': file_path,
        'mime': mime
    };

    jQuery.ajax({
        url: ajaxurl,
        type: "POST",
        data: data,
        success: function(return_data, textStatus, jqXHR) {
            parsedData = kalimahJS.parseJSON(return_data);
            window.open(parsedData.url);
        }
    })

The end result is 0 displayed on the screen. Is there another way to do this?

Kalimah
  • 11,217
  • 11
  • 43
  • 80
  • try to remove the suppress at here `@readfile("$file_path") or die("File not found.");` Maybe the file not found, but you hide the error. What happens if you do? – vaso123 Oct 27 '14 at 09:25
  • I tried both but nothing happens. The file does exist and I have placed an absolute path to it and nothing happened. – Kalimah Oct 27 '14 at 09:32
  • try 2 more things. 1st, try to `var_dump($data);` what it contains? because it seems, `json_encode` fails. 2nd. you can also try, what happens, if you call the php directly. set the `$file_path` and `$file_mime` directly in the ajax file, and call that file. if it's ok, then the data is incorrect what you pass throught `$_POST` – vaso123 Oct 27 '14 at 10:49

3 Answers3

1

Well.

I come here, 2 years later (almost exactly), to post a link to an answer even older, from nearly 5 years ago:

https://stackoverflow.com/a/6668806/1356098

AJAX isn't for downloading files. Pop up a new window with the download link as its address, or do window.location = ....

Note: I changed the code to window.location as suggested by @yitwail

Still... I found some useful information here: https://marksdevserver.com/2011/03/10/downloading-file-ajax/

Community
  • 1
  • 1
Erenor Paz
  • 3,061
  • 4
  • 37
  • 44
1

Since no one has ever answered this question, specifically for WordPress, I thought I'd share my answer:

Say, I want to offer a log file for easy download to users of my plugin (that's what I'm working on right now). What I'd do, is the following:

Register the AJAX action

add_action('wp_ajax_daan_download_log', 'daan_download_log');

Create the function

function daan_download_log()
{
    check_ajax_referer('daan-nonce-value, 'nonce');

    if (!current_user_can('manage_options')) {
        wp_die(__("Hmmm, you're not supposed to be here.", 'my-plugin-name));
    }

    $filename = '/path/to/filename.log';

    if (!file_exists($filename)) {
        wp_die();
    }

    $basename = basename($filename);
    $filesize = filesize($filename);

    header('Content-Description: File Transfer');
    header('Content-Type: text/plain');
    header("Cache-Control: no-cache, must-revalidate");
    header("Expires: 0");
    header("Content-Disposition: attachment; filename=$basename");
    header("Content-Length: $filesize");
    header('Pragma: public');

    flush();

    readfile($filename);

    wp_die();
}

Link to the AJAX action

You can add this, wherever you need to be able to download the file.

<?php $nonce = wp_create_nonce('daan-nonce-value'); ?>

<a href='<?php echo admin_url("admin-ajax.php?action=daan_download_log&nonce=$nonce"); ?>' class="button button-primary">Download Log File</a>
0

Try to add following code also

add_action( 'wp_ajax_nopriv_download_attachment', 'download_attachment' );
Bhumi Shah
  • 9,323
  • 7
  • 63
  • 104