Download (forcing Save As dialog) after using AJAX $.post - javascript

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);

Related

header function filename is not working in PHP

header function filename is not working in PHP. I try to export a CSV file but it always downloads the page name only like export.php
I try so many codes and force download. but I can't. plz anyone help me
enter code here
if(isset($_POST["export"]))
{ include 'database/config.php';
include "database/database.php";
$db = new database();
$fn = "csv_".uniqid().".csv";
$file = fopen($fn, "w");
$query = "SELECT * from wp_terms";
$read = $db -> select($query);
fputcsv($file, array('ID', 'Name', 'slug', 'term group'));
if($read) {
while ($row = $read->fetch_assoc()) {
fputcsv($file, $row);
}
}
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="'.$fn);
fclose($file);
}
This will perfectly work for me so try following code.
add_action("admin_init", "download_csv");
function download_csv() {
if (isset($_POST['download_csv'])) {
global $wpdb;
$sql = "SELECT `sub_email` FROM `wp_terms`";
$rows = $wpdb->get_results($sql, 'ARRAY_A');
if ($rows) {
$csv_fields = array();
$csv_fields[] = "first_column";
$csv_fields[] = 'second_column';
$current_date = date("Y-m-d");
$output_filename = 'subscriber_list'.$current_date.'.csv';
$output_handle = #fopen('php://output', 'w');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Description: File Transfer');
header('Content-type: text/csv');
header('Content-Disposition: attachment; filename=' .
$output_filename);
header('Expires: 0');
header('Pragma: public');
$first = true;
// Parse results to csv format
foreach ($rows as $row) {
// Add table headers
if ($first) {
$titles = array();
foreach ($row as $key => $val) {
$titles[] = $key;
}
fputcsv($output_handle, $titles);
$first = false;
}
$leadArray = (array) $row; // Cast the Object to an array
// Add row to file
fputcsv($output_handle, $leadArray);
}
//echo 'test';
// Close output file stream
fclose($output_handle);
die();
}
}
}

PHP & ZipArchive() - Failed to load PDF document

Good afternon, i have a form that in determined field it open a window or windows to display a specific PDF. The folder where is the path, it can there is just a PDF or a ZIP file with multiples PDF's inner according to the input filled value.
This is blur() event part on the whole my code that calls the windows and pass the values to the "arquivo.php" and "pdf.php", one is to check if is just a PDF or a ZIP, if was a PDF this return on my form informing that is a PDF just and after open just a window to display, this part is ok
JavaScript/HTML code:
///////////PASS THE VALUES TO "arquivo.php"////////////////
$.post("arquivo.php", {nprocesso: document.getElementById("processo").value}, function(data){
$( "#content3" ).html( data ); /*<-- return in this content if is a PDF or a ZIP(when is a zip it returns how many PDF's there are inner ZIP file too)*/
////////////THIS PART IS TO CREATE JUST A WINDOW OR MULTIPLES WINDOWS PASSING THE VALUES RETURNED IN THE "content3" TO "pdf.php" TO DISPLAY IT/THEM//////////////////
setTimeout(function(){
if(document.getElementById("content3").innerText == "PDF"){
window.open("pdf.php/"+document.getElementById("processo").value, '_blank', "toolbar=yes,scrollbars=yes,resizable=yes,width=800,height=800");
}else{
var QuantPDF = Number(document.getElementById("content3").innerText.slice(Number(document.getElementById("content3").innerText.lastIndexOf(','))+1, document.getElementById("content3").innerText.length));//Number(document.getElementById("content3").innerText.replace(/[^0-9]/g, ""));
var NomesPDFS = []; NomesPDFS = document.getElementById("content3").innerText.slice(3, document.getElementById("content3").innerText.length-2).split(',');
if(QuantPDF > 1){
for(var i = 0; i < QuantPDF; i++){
window.open("pdf.php/"+document.getElementById("processo").value+"/"+NomesPDFS[i], '_blank', "toolbar=yes,scrollbars=yes,resizable=yes,width=800,height=800");
}
}else{
window.open("pdf.php/"+document.getElementById("processo").value, '_blank', "toolbar=yes,scrollbars=yes,resizable=yes,width=800,height=800");
}
}
document.getElementById('closeBtn').click();
}, 1000);
}
This is the "arquivo.php", where check if is just a PDF or a ZIP file, and extract if was a zip
Arquivo.php code:
<?php
session_start();
//////////THIS PART CHECK THAT FILE IS A PDF AND RETURN TO MY JAVASCRIPT CODE/////////
if(file_exists('//dsbimrj16/Vinculacao_Cadastro_Gestor/'.$_POST['nprocesso'].'.pdf')){
echo 'PDF';
$_SESSION['file'] = "PDF";
}else{
//////////THIS PART CHECK THAT FILE IS A ZIP AND RETURN TO MY JAVASCRIPT CODE/////////
echo 'ZIP';
$_SESSION['file'] = "ZIP";
$zip = new ZipArchive;
$path = '//dsbimrj16/Vinculacao_Cadastro_Gestor/'.$_POST['nprocesso'].'.zip';
///////////////////////////////////////////////////////////////////
if($zip->open($path) === true){
//////////THIS PART IT OPENS THE ZIP AND EXTRACT/////////
if(!file_exists('//dsbimrj16/Vinculacao_Cadastro_Gestor/'.$_POST['nprocesso'])){
mkdir('//dsbimrj16/Vinculacao_Cadastro_Gestor/'.$_POST['nprocesso'], 0777, true);
}
for($i = 0; $i < $zip->numFiles; $i++){
$zip->extractTo('//dsbimrj16/Vinculacao_Cadastro_Gestor/'.$_POST['nprocesso'], array($zip->getNameIndex($i)));
$path = '//dsbimrj16/Vinculacao_Cadastro_Gestor/'.$_POST['nprocesso'];
$files = scandir($path); array_shift($files); array_shift($files);
$file = array(); $filename = array();
///////NOW I CATCH THE PDF's NAMES AND THE QUANTITY AND RETURN TO JAVASCRIPT CODE///////
$file[$i] = '//dsbimrj16/Vinculacao_Cadastro_Gestor/'.$_POST['nprocesso'].'/'.$files[$i];
$filename[$i] = '//dsbimrj16/Vinculacao_Cadastro_Gestor/'.$_POST['nprocesso'].'/'.$files[$i];
$nomes_pdfs = array();
$nomes_pdfs[$i] = substr(substr($filename[$i], strpos($filename[$i], $_POST['nprocesso'])+26, strlen($filename[$i])), 0, strpos(substr($filename[$i], strpos($filename[$i], $_POST['nprocesso'])+26, strlen($filename[$i])), '.pdf')).',';
echo $nomes_pdfs[$i];
}
$zip->close();
$path = '//dsbimrj16/Vinculacao_Cadastro_Gestor/'.$_POST['nprocesso'];
$files = scandir($path);
array_shift($files); array_shift($files); $_SESSION['quantidade_pdf'] = count($files);
echo $_SESSION['quantidade_pdf'];
}
}
?>
My problem actually is partially on "pdf.php" where the window load with the values returned of the "content3". When is a single PDF, the window display normally, but when is a ZIP file with multiples PDF's, the first PDF display correctcly, but starting in the second and on, it doesn't display. show a this error: "Failed to load PDF document".
pdf.php code:
<?php
header ('Content-type: text/html; charset=utf-8');
if(file_exists('//dsbimrj16/Vinculacao_Cadastro_Gestor/'.substr($_SERVER['REQUEST_URI'], strrpos($_SERVER['REQUEST_URI'], '/')+1).'.pdf') && is_file('//dsbimrj16/Vinculacao_Cadastro_Gestor/'.substr($_SERVER['REQUEST_URI'], strrpos($_SERVER['REQUEST_URI'], '/')+1).'.pdf')){
$processo = substr($_SERVER['REQUEST_URI'], strrpos($_SERVER['REQUEST_URI'], '/')+1);
$file = '//dsbimrj16/Vinculacao_Cadastro_Gestor/'.$processo.'.pdf';
$filename = '//dsbimrj16/Vinculacao_Cadastro_Gestor/'.$processo.'.pdf';
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
header('Accept-Ranges: bytes');
#readfile($file);
}else{
/////////////////////HERE IS THE PART WHEN IS A ZIP////////////////////////
///////*This part it's only to check if the folder extract exists*/////////
function folder_exist($folder){ $path = realpath($folder); return ($path !== false AND is_dir($path)) ? $path : false; }
chdir('//dsbimrj16/Vinculacao_Cadastro_Gestor/');
$folder = '/'.substr(substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], 'p/')+2), 0, strpos(substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], 'p/')+2), '/')).'/';
if(FALSE !== ($path = folder_exist($folder))){
/////*Here start the part where the code catch the PDF's and display*/////
$pasta = substr(substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], 'p/')+2), 0, strpos(substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], 'p/')+2), '/'));
$processo = substr($_SERVER['REQUEST_URI'], strrpos($_SERVER['REQUEST_URI'], '/')+1);
$file = '//dsbimrj16/Vinculacao_Cadastro_Gestor/'.$pasta.'/'.$processo.'.pdf';
$filename = '//dsbimrj16/Vinculacao_Cadastro_Gestor/'.$pasta.'/'.$processo.'.pdf';
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
header('Accept-Ranges: bytes');
#readfile($file);
}else{
die('<h2 style="background-color:#FA5858"><center>Não foi encontrado a inicial do processo. Verifique se o mesmo encontra-se na pasta.</center></h2>');
}
}
?>
What i'm doing wrong ? I've already checked the folder, the file is in and the name and the path is the same that the code are putting to display

Trying to download file from remote server using Ajax with Codeigniter not working

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

'save as' box with Javascript/PHP

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 );

Generating Files with JavaScript and PHP

I am trying to generate a file to download. With JavaScript I call a PHP file to process my request and send back the result in a way it should be possible to download it. But instead of making it available for download it simply display the code.
PHP
function export()
{
// Get a database object.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Select fields to get.
$fields = array(
$db->quoteName('params')
);
// Conditions for which records should be get.
$conditions = array(
$db->quoteName('element') . ' = ' . $db->quote('plugin_name'),
$db->quoteName('folder') . ' = ' . $db->quote('system')
);
// Set the query and load the result.
$query->select($fields)->from($db->quoteName('#__extensions'))->where($conditions);
$db->setQuery($query);
$results = $db->loadResult();
// Namming the filename that will be generated.
$name = 'file_name';
$date = date("Ymd");
$json_name = $name."-".$date;
// Clean the output buffer.
ob_clean();
echo $results;
header('Content-disposition: attachment; filename='.$json_name.'.json');
header('Content-type: application/json');
}
JavaScript
function downloadFile() {
var fd = new FormData();
fd.append('task', 'export');
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", uploadComplete, false);
xhr.open("POST", "my_php_file");
xhr.send(fd);
}
HTML file
<button class="btn btn-primary btn-success" type="button" onclick="downloadFile()"></button>
UPDATE MY CODE
You need to call any header function calls before you output data. Otherwise you will get a headers "Headers already sent" warning, and the headers will not be set.
Example:
...
// Namming the filename that will be generated.
$name = 'file_name';
$date = date("Ymd");
$json_name = $name."-".$date;
header('Content-disposition: attachment; filename='.$json_name.'.json');
header('Content-type: application/json');
// Clean the output buffer.
ob_clean();
echo $results;
An example
<?php
ob_start();
echo "some content to go in a file";
$contentToGoInFile = ob_get_contents(); //this gets the outputted content above and puts it into a varible/buffer
ob_end_clean();
header('Content-disposition: attachment; filename='.$json_name.'.json');
header('Content-type: application/json');
echo $contentToGoInFile;
exit; //stops execution of code below
example with your code
$results = $db->loadResult();
// Namming the filename that will be generated.
$name = 'file_name';
$date = date("Ymd");
$json_name = $name."-".$date;
ob_start();
echo $results;
$contentToGoInFile = ob_get_contents(); //this gets the outputted content above and puts it into a varible/buffer
ob_end_clean();
header('Content-disposition: attachment; filename='.$json_name.'.json');
header('Content-type: application/json');
echo $contentToGoInFile;
exit

Categories

Resources