On my website I have a JavaScript function that using PHP function creates a file locally on my server (same directory as the website files). The name of this file is known only to these JavaScript and PHP functions.
I want to open a regular 'Save As' box to the user to download this file.
Is there a way to do this using Javascript/PHP in a manner that will work for Firefox, Chrome and Explorer/Edge? (Only the Javascript/PHP know the file name)
This is the PHP example:
file_put_contents($filename,$txt);
header('content-type: application/text');
header('content-disposition: attachment; filename=' . $filename);
readfile($filename);
In chrome & firefox it saves automatically and in IE a window opens so if a user has not changed their settings by default will they see the where to save dialog regardless of the browser they're using. go to
https://support.google.com/chrome/answer/95574?hl=en-GB
For more information. You can use php code for downloading the file from your server.
header('content-type: application/[type]');
header('content-disposition: attachment; filename=yourfile.file-extension');
readfile('yourfile.file-extension');
for a large file, you can use
function readfileChunked($filename, $retbytes=true){
$chunksize = 1*(1024*1024);
$buffer = '';
$cnt = 0;
$handle = fopen($filename, 'rb');
if ($handle === false) {
return false;
}
while (!feof($handle)) {
$buffer = fread($handle, $chunksize);
echo $buffer;
ob_flush();
flush();
if ($retbytes) {
$cnt += strlen($buffer);
}
}
$status = fclose($handle);
if ($retbytes && $status) {
return $cnt; // return num. bytes delivered like readfile() does.
}
return $status;
}
header('Pragma: public'); // required
header('Expires: 0'); // no cache
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private',false);
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename="'.$name.'"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '. get_remote_size($url) );
header('Connection: close');
readfileChunked( $url );
Related
I am trying to download a pdf when clicking on a link.
I called function onlick of a link and in Codeigniter i wrote a function to download PDF file but when running URL ,file is downloaded but when triggered using click of link, its not working.
Controller:
function downloadpdf($pid)
{ set_time_limit(0);
$url="http://www.malayatourism.com/uploads/images/packages/pdf/$pid.pdf";
$file = basename($url);
$fp = fopen($file, 'w');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FILE, $fp);
$data = curl_exec($ch);
curl_close($ch);
fclose($fp);
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
echo "success";
}
My code ajax:
function DownLoadPdf(id)
{
url = "<?php echo base_url();?>admin/packages/downloadpdf/"+id;
$.ajax({
type:'POST',
url: url,
data : { pid : id},
success : function(response) {
console.log(response);
},
error : function(response) {
console.log("error");
}
});
}
View:
echo ' Download Attachment';
As far as ajax is concerned you cannot do that via ajax because ajax is not made for this purpose,its an asynchronous call that will give you a result. But you can do this without using any jquery, ajax at all
<a href="http://www.malayatourism.com/uploads/images/packages/pdf/$pid.pdf" download> Download Attachment</a>
Where $pid is the id you want to download the file. The download attribute will force the file to download. Cheers
My file download works great. The file is delivered correctly. But I want to make it prettier.
Is there a way to set a favicon and a window title, if I click on a html-download link to a file in a new tab?
the file is generated and streamed by php.
client part:
<a target="_blank" tabindex="0" href="/path/to/file-download/interface" >
server stream, while $file is some array holding file information:
if (file_exists($file['path'])) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $file['path']);
if( strstr($mime, "image") !== false ){
header('Content-Type: '.$mime);
header('Content-Disposition: filename='.basename($file['path']));
} else {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file['path']));
}
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($file['path']));
ob_clean();
flush();
readfile($file['path']);
exit;
} else {
error_log("File for download >".$file['path']."< not found.");
return false;
}
UPDATE
An additional problem is, that there is a favicon already in the root folder, but I want to show a different one.
I have a webapp that simulates a terminal. Every command is posted via AJAX using the following script (portion):
AJAX/jQuery
$.post("sec/cmd_process.php", { n : n } )
.done(function(data){
output.append(display(data));
});
If the user types download log into the terminal, the following script - on sec/cmd_process.php is executed:
PHP
if(isset($_POST['n'])){
echo $_POST['n'];
$t = explode(' ', $_POST['n']);
if(strtolower($t[0])=='download'){
if(!isset($t[1])) shout_error("No download specified");
//Download Log
elseif($t[1]=='log'){
$stmt = $dbh->prepare("SELECT * FROM `tap_log` ORDER BY `time`");
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($rows as $row) {
$user = user_by_id($row['user']);
$data.= "{$row['time']} - User {$user['id']} ({$user['name1']} {$user['name2']}) - {$row['information']} ({$row['subject']})".PHP_EOL;
}
$handle = fopen('log.txt','w+');
fwrite($handle, $data);
$path = 'log.txt';
header('Content-Transfer-Encoding: binary');
header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($path)).' GMT');
header('Accept-Ranges: bytes');
header('Content-Length:'.filesize($path));
header('Content-Encoding: none');
header('Content-Disposition: attachment; filename='.$path);
readfile($path);
fclose($handle);
}
}
}
What I want to happen is for the generated file, log.txt, is downloaded via the Save As... dialog. This code works if you directly visit a PHP page with those headers, but how can I make it work through jQuery/AJAX?
The simplest solution I found was to return a <script> tag forwarding the location to a forced download page:
<script type='text/javascript'>
location.href='sec/download.php?file=log.txt&type=text';
</script>
sec/cmd_process.php
$handle = fopen('log_'.time().'.txt','w+');
fwrite($handle, $data);
echo "Please wait while the file downloads...";
echo "<script type='text/javascript'>location.href='sec/download.php?file=log.txt&type=text';</script>";
fclose($handle);
sec/download.php
<?php
$filename = $_GET['file'];
$filetype = $_GET['type'];
header("Content-Transfer-Encoding: binary");
header("Last-Modified: ".gmdate('D, d M Y H:i:s',filemtime($filename))." GMT");
header("Accept-Ranges: bytes");
header("Content-Length: ".filesize($filename));
header("Content-Encoding: none");
header("Content-Type: application/$filetype");
header("Content-Disposition: attachment; filename=$filename");
readfile($filename);
Try to make a download page with pure php.
For those people that have javascript enabled, I plan to extend the download page with some feedback.
Have done some protyping...
when the user press on the download button (post) the download starts.
There is no page change and the java scripts are still executable on the download page.
Is this something that could rely on, that the javascript still executes after a forced download?
simple example, test.php:
<?php
if (!isset($_POST["submit"])) {
$content = '
<script type="text/javascript">
var count = 0;
function tick(){
count++;
console.log("tick() " + count);
setTimeout("tick()", 1000);
}
tick();
</script>
<form method="post" action="">
Download file</br>
<input type="submit" name="submit" value="Submit" />
</form>
';
echo $content;
} else {
$file = 'contentFile.zip';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename='.basename($file));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
}
?>
I have this php file:
<?php
$file = 'ico/people.gif';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
?>
This works.
But the line $file = 'ico/people.gif'; should be removed, and instead the script is to receive the url from another document.
This other document has this JavaScript in header:
<script>
function save_file(url){
document.location.href = "save.php?image="+url;
}
</script>
And this button in body:
<input type="button" onclick="save_file('ico/people.gif')" value="Save image">
How can I make this work together?
people.gif is just an example. It should, when I get it to work, be replaced by a string, that can represent any image.
Basically, all I want is a save image button.
$file = $_GET['image'];
instead of your first line should do it.