On button click I'm downloading a text file via PHP in AJAX.
Here is my code. I only get an alert of file contents instead of downloading the file.
<?php
$cpy1 = $_POST['cpy1'];
file_put_contents("download.txt",$cpy1);
$file ="download_link.txt";
if(!file_exists($file)) die("I'm sorry, the file doesn't seem to exist.");
$type = filetype($file);
// Get a date and timestamp
$today = date("F j, Y, g:i a");
$time = time();
// Send file headers
header("Content-type: $type");
header("Content-Disposition: attachment;filename=download_link.txt");
header("Content-Transfer-Encoding: binary");
header('Pragma: no-cache');
header('Expires: 0');
// Send the file contents.
set_time_limit(0);
readfile($file);
?>
Help please.
I got the desired OP by below code. Was created a hidden download btn (hyperlink of text file) and on success made a click on it
success: function(data){
swal("Download List", data, "success");
// alert(data);
$('#getfile')[0].click();
}
This gave popup with text file download
I guess it just because of your third part application (e.g. IDM). Please disable/uninstall it first then your code should work as you want.
Related
On my site, if a user chooses to download a file, I set a session variable called $step to "downloadEnd" and my PhP code downloads a template file using the following code:
if ($step == "downloadEnd") {
$file = "Template.xlsx";
header('Content-Description: File Transfer');
header('Content-Type: ' . $mime);
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file) . "\"");
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
readfile($file);
exit();
$step = "nextStep"; // THIS IS THE LINE THAT DOES NOT EXECUTE
}
if ($step == "nextStep") {
// New Information Rendered to the User
}
The above code works, EXCEPT, that the last line of the first does not appear to 'execute'. In other words, after the download is complete, I want the user to see a new page with new text which is in a separate if statement ... if ($step == "downloadStart") ... but it never gets there. I believe it is because I need to somehow 'trick' the server into thinking there has been another user POST from the browser to the server AFTER the file downloads so that PhP iterates through all the 'if' statements and renders the new information to the user. I cannot seem to find a way to either: (i) have PhP trigger a page refresh after the file is done downloading; or (ii) trick the server into thinking it needs to refresh the page once the file is done. Any help would be appreciated.
I should add that I know the exit() at the end stops the PhP script from executing, but if you omit that line of code, the .xlsx file will be corrupted. I should also add that I tried the alternative fopen($file), fread($file), fclose($file) and that too gave me a corrupted .xlsx download, which is a problem others appear to have encountered as evidenced by other posts on Stack Overflow.
I think I see what your problem is. By running exit() you tell PHP to stop what it's doing. Try the following code:
if ($step == "downloadEnd") {
$file = "Template.xlsx";
header('Content-Description: File Transfer');
header('Content-Type: ' . $mime);
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file) . "\"");
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
readfile($file);
$step = "nextStep"; // THIS IS THE LINE THAT DOES NOT EXECUTE
}
if ($step == "nextStep") {
// New Information Rendered to the User
}
Also, you might want to look into JavaScript for refreshing the page after a document has downloaded.
Edit
If you are wanting to show this like a "click link if file did not properly download" page would be then the following should work:
if ($step == "downloadEnd") {
$fileURL = "https://example.com/path/to/Template.xlsx";
echo('<script>window.open("' . $fileURL . '", "_blank");</script>');
$step = "nextStep";
}
if ($step == "nextStep") {
// New Information Rendered to the User
}
You can use something like ob_end() or ob_end_clean() but it would be better to put the new information on a separate page and redirect the user there with echo('<script>window.location.replace("new.php")</script>'). Hope that helped! Also, PHP is a server-side language and therefore cannot tell when a file has finished downloading on the client.
I have website which uses ajax for most of cases. I have allowed user to upload image through ajax. When user clicks on a button the image is displayed in modal through an ajax call.
Now, I want to user to begin his download by clicking on image without closing the modal or refreshing. I did tried with href. It works fine but, as I mentioned, I want to keep user on same page with modal open.
The code I have tried untill now is:
$(document).ready(function(){
var imgname;
imgname = '';
$("#modalimage").click(function(){
imgname = $("#downloadimg").val();
downloadImage(imgname);
})
})
function downloadImage(imagename){
$.ajax({
type : "POST",
url : "download.php",
data : { imagename : imagename } ,
success : function(response){
alert('success');
}
})
}
download.php code is:
if ( isset($_POST['imagename']) ) {
$filename = $_POST['imagename'];
$filepath = 'images/'.$filename;
}
echo $filepath;
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($filepath));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filepath));
readfile($filepath);
The problem here is when ajax make call to download.php it create a response in form of some binary codes and small image codes without initiating the download. Is it possible to download the image by ajax call?
Instead of calling it by ajax place this link:
<a href="download.php?imagename=<?php echo urldecode($imagename); ?>">
Clich here to download
</a>
where $imagename is the file path. And the link content can be the text or a thumbnail or whatever you want.
And just change the download.php code to get the image through $_GET and not $_POST and, important, remove the echo that there is in there, there should be no other content than the headers and the file content:
if ( isset($_GET['imagename']) ) {
$filename = $_GET['imagename'];
$filepath = 'images/'.$filename;
}
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($filepath));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filepath));
readfile($filepath);
You will not be redirected to the file and the file will be downloaded. No need of ajax for this.
In case you really prefer using javascript you could create the link dinamically:
$(document).ready(function(){
$("#modalimage").click(function(){
var imgname = $("#downloadimg").val();
var link = document.createElement("a");
link.download = name;
link.href = 'download.php?imagename=' + encodeURI(imgname);
link.click();
});
})
I am trying to download a CSV file with PHP but I can not make it to get the dialog box.
I have changed the headers and used the readfile() function as shown here
This is my code:
$nodeId = 'something';
$filename = "/var/www/dkar/ruralBroadband/ruralApp/rural/csvExports/$nodeId.csv";
header('Content-type: text/csv');
header('Content-disposition: attachment; filename ="report.csv"');
readfile($filename);
** EDIT **
Tried also with this as suggested:
header('Content-Disposition: attachment; filename="report.csv"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize('report.csv'));
When I am checking the response in Firebug I can see the whole CSV file returned. Also the headers change into:
Content-Type text/csv
Content-disposition attachment; filename ="report.csv"
So I can not figure out why I dont get the dialog box to save the file.
Add these headers:
header('Content-Disposition: inline; filename="report.csv"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($filename));
After all I didn't use the above method and I did that, which works fine and its more straight forward:
var ajaxurl = 'exportNodeData.php', // script to run
data = {nodeId:nodeId}; // data to pass
$.post(ajaxurl, data, function (response) {
document.location.href = 'https://www.ruralauditor.gr/csvExports/'+nodeId+'.zip';
});
This is the ajax request, which I execute in order to create the CSV file (which is also zipped). I then use this line:
document.location.href = 'https://www.ruralauditor.gr/csvExports/'+nodeId+'.zip';
in order to force the download of the file.
I got stuck with the code left by the first programmer of the current webpage that I'm on. He create his own custom framework.
My problem is that I have created a function for file export cause there is a feature wherein I should export the query to textfile so client/user download it automatically via forcing the browser to download the generated file: heres the code of my force download.
Note: I have already search with others forums as well as at Stackoverflow but I can't find an answer. This is my current code:
if(!defined('APPLICATION_RUNNING')){
header("HTTP/1.0 404 Not Found");
die('acces denied');
}
if(defined('ANNOUNCE')){
echo "\n<!-- loaded: ".__FILE__." -->\n";
}
if(!class_exists('APP_Ajax')){
class APP_Ajax extends APP_Base_Ajax
{
function textfiles()
{
global $apptemplate, $appform, $appdb;
if(!$appform->form_valid($this->post['formid'])) // if not b\valid form
{
json_return_error(5);
}
else
{
if(!empty($this->post['form'])) //if the post of form is not empty
{
$e = array();
}
else
{
json_return_error(6);//alert if form is empty
}
if(empty($this->post['form']['rowid']))
{
json_return_error(252); // if rowid is empty then raise error
}
else
{
$rets = $this->post['form']['rowid'];
$ids = explode(',',$rets);
foreach ($ids as $kids)
{
$sql = pg_query("SELECT * from tbl_patient WHERE id='$kids'");
$info = pg_fetch_assoc($sql);
$text[] = ucwords($info['firstname']." ".$info['mi']." ".$info['lastname']).",".$info['medicalrecordnumber'].",".$info['referraldate'];
}
$output = implode( "\r\n" , $text );
$randfile = rand(12345689,999999999)."_".date('m-d-Y');
$f = fopen("templates/default/exports/".$randfile.".txt", "w");
fwrite($f, $output);
fclose($f);
$file_name = ABS_PATH.'templates/default/exports/'.$randfile.'.txt';
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_name)).' GMT');
header('Cache-Control: private',false);
header('Content-Type: text/plain');
header('Content-Disposition: attachment; filename="'.basename($file_name).'"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($file_name));
header('Connection: close');
readfile($file_name);// push it out
}
}
}
}
The code above produce no error, the file where created on the path I create but
the problem is that "No save as" or something, the browser do not download a file. When I use httpfox to view the headers, etc, etc, the result of the query is displayed on httpfox content tab, so nothings wrong with the code except that I want the browser to show the Download file(Save as dialog) so the user can save it to there Hard drives..
Note 2#: When I create a download link like Download, when I click the download link, the page returns me to the main page and no downloads at all.
Please give me a script or advice on how to work on this stuff. Thank you in advance.
Tell me if I'm missing something here.
Oops forgot to tell you, the website I'm on it do not allow external access to file for security that's why I can't link the export file it to other page for download. :)
By going through the Codeigniter documentation, I am using the following code to force download files from my server.
function download($file_id){
$file = $this->uploadmodel->getById($file_id); //getting all the file details
//for $file_id (all details are stored in DB)
$data = file_get_contents($file->full_path); // Read the file's contents
$name = $file->file_name;;
force_download($name, $data);
}
The code is working file for images, but when it comes with the case of PDF files, it is not working. I have not tested it for all file extensions, but since it is not working for PDF, it might not work for other various file types.
Any solution?
I've had similar problems. I think the problem resides in certain mime's and headers sent to the browser(s). I've end up using the code I found here http://taggedzi.com/articles/display/forcing-downloads-through-codeigniter. Use the function below instead of force_download. It has worked for me so far.
function _push_file($path, $name)
{
// make sure it's a file before doing anything!
if(is_file($path))
{
// required for IE
if(ini_get('zlib.output_compression')) { ini_set('zlib.output_compression', 'Off'); }
// get the file mime type using the file extension
$this->load->helper('file');
$mime = get_mime_by_extension($path);
// Build the headers to push out the file properly.
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 ($path)).' GMT');
header('Cache-Control: private',false);
header('Content-Type: '.$mime); // Add the mime type from Code igniter.
header('Content-Disposition: attachment; filename="'.basename($name).'"'); // Add the file name
header('Content-Transfer-Encoding: binary');
header('Content-Length: '.filesize($path)); // provide file size
header('Connection: close');
readfile($path); // push it out
exit();
}
}
Hope it helps.
It is working for .pdfs also.
Check the path to the file - that might be the problem.
I, too, had that problem, but when I corrected the path to the file, it worked perfectly.
The following is how I wrote the code:
if($src == "xyyx")
{
$pth = file_get_contents(base_url()."path/to/the/file.pdf");
$nme = "sample_file.pdf";
force_download($nme, $pth);
}
Try this, I think its best practice for that problem.
function download($file_id)
{
$this->load->helper('file'); // Load file helper
$file = $this->uploadmodel->getById($file_id); //Get file by id
$data = read_file($file->full_path); // Use file helper to read the file's
$name = $file->file_name;;
force_download($name, $data);
}