kcalder
asked on
ajax php file download and update mysql database field
I am starting to get to grips with ajax and need some assistance to code for form submission in which a mysql field value is updated and a file is downloaded. The principle of the routine is to checkout/download a file for revision and, having done so, ensure that nobody else can checkout the same file.
The first part of the problem I have done by simply using a standard php update function when the form is submitted. However, I am trying to use ajax to manage file download and I am having difficulty getting it configured.
I have attached a screenshot of the form page which is a list of radio buttons and a 'Checkout' (submit) button. When one of the radio buttons is selected and the button clicked, the database entry is updated to set the docCheckedOut field in the document table to true. At the same time a file download dialog should appear, and this isn't happening.
The pertinent parts of the code are shown below. All assistance gratefully received!
The first part of the problem I have done by simply using a standard php update function when the form is submitted. However, I am trying to use ajax to manage file download and I am having difficulty getting it configured.
I have attached a screenshot of the form page which is a list of radio buttons and a 'Checkout' (submit) button. When one of the radio buttons is selected and the button clicked, the database entry is updated to set the docCheckedOut field in the document table to true. At the same time a file download dialog should appear, and this isn't happening.
The pertinent parts of the code are shown below. All assistance gratefully received!
<!-- ajax functions all contained in lib.js-->
<!-- Process the download -->
function downloadFile(fileName)
{
// Takes the file information and passes it to downloadFile.php
xmlhttp = getxmlhttpObject();
if (xmlhttp == null)
{
alert ("Browser does not support HTTP Request");
return;
}
var serverPage = "../includes/downloadFile.php";
obj = document.getElementById(fileName);
processAjax(serverPage, obj, "post", "fileName");
}
<!-- process the ajax request -->
function processAjax(serverPage, obj, getOrPost, str)
{
// Get an xmlhttpRequest object
xmlhttp = getxmlhttpObject();
if (getOrPost == "get")
{
xmlhttp.open("GET", serverPage);
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
obj.innerHTML = xmlhttp.responseText;
}
xmlhttp.send(null);
}
else
{
xmlhttp.open("POST", serverPage, true)
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
obj.innerHTML = xmlhttp.responseText;
}
xmlhttp.send(str);
}
}
<!-- get the xmlhttp object -->
function getxmlhttpObject()
{
// Create a boolean to check for a valid MS IE browser instance
var xmlhttp = false;
// Check if IE is being used
try
{
// If the js version is > 5
xmlhttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
// If js version <= 5, then use the older activeX object
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
catch(E)
{
// Otherwise a non-IE browser is being used
xmlhttp = false;
}
}
// If not using IE, create a js instance of the object
if (!xmlhttp && typeof XMLHttpRequest != 'undefined')
{
xmlhttp = new XMLHttpRequest();
}
return xmlhttp;
}
<!-- php file download routine (courtesy of Zubrag) -->
<?php
// downloadFile.php
// Download a file (with download resumption capability)
// Define the downloadable directory
define('BASE_DIR','http://MYDOMAIN/docsGeneral/');
/*
This function takes a path to a file to output ($file),
the filename that the browser will see ($name) and
the MIME type of the file ($mime_type, optional).
If you want to do something on download abort/finish,
register_shutdown_function('function_name');
*/
if(!is_readable($file)) die('File not found or inaccessible!');
$size = filesize($file);
$name = rawurldecode($name);
/* Figure out the MIME type (if not specified) */
$known_mime_types=array("pdf" => "application/pdf",
"txt" => "text/plain",
"html" => "text/html",
"htm" => "text/html",
"exe" => "application/octet-stream",
"zip" => "application/zip",
"doc" => "application/msword",
"xls" => "application/vnd.ms-excel",
"ppt" => "application/vnd.ms-powerpoint",
"gif" => "image/gif",
"png" => "image/png",
"jpeg"=> "image/jpg",
"jpg" => "image/jpg",
"php" => "text/plain");
if ($mime_type=='')
{
$file_extension = strtolower(substr(strrchr($file,"."),1));
if(array_key_exists($file_extension, $known_mime_types)) $mime_type=$known_mime_types[$file_extension];
else $mime_type="application/force-download";
}
@ob_end_clean(); //turn off output buffering to decrease cpu usage
// required for IE, otherwise Content-Disposition may be ignored
if(ini_get('zlib.output_compression')) ini_set('zlib.output_compression', 'Off');
header('Content-Type: ' . $mime_type);
header('Content-Disposition: attachment; filename="'.$name.'"');
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');
/* The three lines below basically make the
download non-cacheable */
header("Cache-control: private");
header('Pragma: private');
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
// multipart-download and download resuming support
if(isset($_SERVER['HTTP_RANGE']))
{
list($a, $range) = explode("=",$_SERVER['HTTP_RANGE'],2);
list($range) = explode(",",$range,2);
list($range, $range_end) = explode("-", $range);
$range=intval($range);
if(!$range_end) $range_end=$size-1;
else $range_end=intval($range_end);
$new_length = $range_end-$range+1;
header("HTTP/1.1 206 Partial Content");
header("Content-Length: $new_length");
header("Content-Range: bytes $range-$range_end/$size");
}
else
{
$new_length=$size;
header("Content-Length: ".$size);
}
/* output the file itself */
$chunksize = 1*(1024*1024); //you may want to change this
$bytes_send = 0;
if ($file = fopen($file, 'r'))
{
if(isset($_SERVER['HTTP_RANGE'])) fseek($file, $range);
while(!feof($file) && (!connection_aborted()) && ($bytes_send<$new_length))
{
$buffer = fread($file, $chunksize);
print($buffer); //echo($buffer); // is also possible
flush();
$bytes_send += strlen($buffer);
}
fclose($file);
}
else die('Error - can not open file.');
die();
form.jpg
I've just had to learn about AJAX and file downloading.
Here is what I found.
When a user selects a file download (non AJAX, normal file browsing), the browser generates a request, the server responds with appropriate headers which tell the browser that the data that follows is for the user and not to be automatically handled by the browser.
When AJAX makes the request, it is AJAX that gets the response. AJAX does NOT invoke a file save dialogue or anything like that.
The solution I had was to create a hidden iframe whose URL was the downloader. The iframe is part of the browser, so when it gets the headers saying this is a file download, the browser would open the file save dialogue.
Here is what I found.
When a user selects a file download (non AJAX, normal file browsing), the browser generates a request, the server responds with appropriate headers which tell the browser that the data that follows is for the user and not to be automatically handled by the browser.
When AJAX makes the request, it is AJAX that gets the response. AJAX does NOT invoke a file save dialogue or anything like that.
The solution I had was to create a hidden iframe whose URL was the downloader. The iframe is part of the browser, so when it gets the headers saying this is a file download, the browser would open the file save dialogue.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I am closing this question out because I have decided to take a different approach using jQuery. I am still having difficulty making that work but it seems appropriate to develop a separate question. Thanks for your assistance.
ASKER
Open in new window