AJAX File Download

by Lasantha Samarakoon on Sunday, November 15, 2009

Good day guys, today I’m going to show you how to download a file without reloading or refreshing the current page. So to do that, I will use my preferred server-side language PHP, HTML and little bit of CSS.

So the problem is, I have a link named “Download” and when I click on that link browser’s file download box should be visible without refreshing or navigating away from the page. So to solve this problem I will use an AJAX technique. Let’s think how we can implement this in AJAX.

My solution is this. I will create a HTML inner frame in my web page. And when I click on the download link, something will be loaded in the inner frame. So this is how I solved that.

I will create 2 web pages, one is pure HTML and other one is PHP. The HTML page contains the inner frame and download button. The PHP file is used to dynamically read the content of the downloadable file and write them to the client.

<!-- index.htm -->  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>AJAX Download</title>
</head>

<body>

<!-- this inner frame is hidden by css -->
<iframe name="ajax_frame" style="display: none;"></iframe>

<!-- download link -->
<a href="download.php" target="ajax_frame">Download</a>

</body>
</html>

Here I named inner frame as “ajax_frame” and in the link I set the target to that inner frame. So when I click on the link, the content will be loaded in the inner frame. And I set the display style of the inner frame to “none” to hide the frame in the web page. So the user cannot see the inner work of the web page.

<?php // download.php  
// send http header 'content-type'
header("Content-Type: text/plain");  

// start flushing data  
ob_start();  

// echo data  
echo "hello world";  

// get the flushed data size and send http header attribute 'content-length'  
header("Content-Length: " . ob_get_length());  

// send http header information regarding the file attachment  
header("Content-Disposition: attachment; filename=test.txt; modification-date=\"Sun, 15 Nov 2009 12:50:00 +0530\";");  
?>

Above is the technique I used to push the file content to the client. It’s just a PHP echo with some header commands. In this demonstration I did not used any external file, but I send some content using the echo command. This is really same as reading a text file contents “hello world” in it. Let’s consider line by line.

header("Content-Type: text/plain");

I used header command to send HTTP response headers to the client. Here I send “Content-Type” header indicating the incoming data is belongs to plain text. You can use any other Content-Type regarding to the data you are going to send. As an example, for a PDF file you can send “application/pdf”.

ob_start();
Start flushing data to the client.

echo "hello world";

Echo the content of the file.

header("Content-Length: " . ob_get_length());

Get the length of data flushed to the client and send the header “Content-Length” to the client.

header("Content-Disposition: attachment; filename=test.txt; modification-date=\"Sun, 15 Nov 2009 12:50:00 +0530\";");

Here it is again an HTTP response header, indicating that the flushed data belongs to the file named “test.txt” and the modified date of the file.

So this is all about the solution. If you want to send really an external file to the user, you have to replace line # 9 with commands regarding to open the file, read the content, echo the content and close the file. That’s all.

Leave your comment