0

I want to download asynchronously a file from server. My files are located in 'files' directory - one directory higher than the content of the website.

In my code I have an ajax click event on div witch run asynchronously a php file named 'get_file.php' with some variables (GET method).

This is content of 'get_file.php'

<?php

$dir    =   '../../files/'; 
$file   =   $_GET['file'];  

if (file_exists($dir . $file)) {

            // only for test run a file via ajax
            file_put_contents("test.tht", $dir . $file);

    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($dir . $file));
    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: ' . filesize($dir . $file));
    ob_clean();
    flush();
    readfile($dir . $file);
    exit;
}
?>

Code works corectly in part of transfer variables (because in test file.txt I can find a path and file name), but download doesn't start. What is wrong?

Aros
  • 9
  • 1
  • 3
  • 2
    get_file.php content is missing. – Jakub Matczak Mar 30 '14 at 11:12
  • Edited the post to fix code formatting problems – Pete TNT Mar 30 '14 at 11:14
  • You don't use ajax for that, you just link to the file, and the header will make the file download instead of redirecting. When using ajax, nothing happens, as expected. – adeneo Mar 30 '14 at 11:18
  • But I have two problems: - I don't want to show my files loction, - I have my files one directory higher then www directory – Aros Mar 30 '14 at 11:20
  • 1
    A rewrite rule would do that as well. However, if you want PHP, check http://en.wikipedia.org/wiki/Directory_traversal_attack – Bergi Mar 30 '14 at 12:20
  • possible duplicate of [Handle file download from ajax post](http://stackoverflow.com/questions/16086162/handle-file-download-from-ajax-post) – Robin van Baalen May 16 '14 at 20:37
  • @Robin: That's close, but this is a simpler case: no `POST` is needed; a `GET` will work just fine, and that needs no trickery. – icktoofay May 17 '14 at 06:00

1 Answers1

2

Ajax will not help you here. Instead you can trigger your download by either set the src-attribute of an invisible iFrame or by navigating to the download URL.

// iFrame approach

<iframe  style="display:none" id="downloadFrame" src=""></iframe>

-

<script>
  var iframe = document.getElementById("downloadFrame");
  iframe.src = "get_file.php?file=testfile.txt";
</script>

// OR Navigate to the download url

window.location.href = "get_file.php?file=testfile.txt";

Apart from that you really should check your input in your get_file.php. Users will be able to download everything (../index.php) as long you do not check the incoming filename.

nils
  • 1,668
  • 14
  • 15