I have a js script that saves an image as .jpg in a specific folder on the server:
$data = substr($_POST['imageData'], strpos($_POST['imageData'], ",") + 1);
$decodedData = base64_decode($data);
$fp = fopen("imgdownload/cc.jpg", 'wb');
fwrite($fp, $decodedData);
fclose($fp);
The next step would be for the user to save it on his/her disk, the best would be to open a dialog box "save as" and choose the name and location, but just forcing download to a set location would be a dream.
I've tried:
$file = 'imgdownload/cc.jpg';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: image/jpg');
header('Content-Disposition: attachment; filename='.basename($file));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
And other things without success. What am I doing wrong and how to do it right?
EDIT - this is my JS:
savePicture: function() {
$(this.el).find('canvas').attr('id', 'myCanvas');
var data = document.getElementById("myCanvas").toDataURL();
$.post("api/process.php", {
imageData: data
}, function(data) {
//window.location = data;
});
},
You cannot trigger a download in response to a background AJAX request. You'll have to direct the main browser to the URL where the download occurs. E.g., in your AJAX callback:
window.location = '/download.php';
That means you'll need to store the file server-side in the AJAX upload request to then have it available for download in the separate following request to download.php somewhere.
Related
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 would like to download pdf file by clicking on button and pdf file is opened in new tab.
My pdf file URL is hidden. I cannot use pdf file URL to download it.
pdf file is on the web server.
I want to download it by using puppetter in headless mode.
scrape.js
const fs = require('fs');
const puppeteer = require('puppeteer');
// set up, invoke the function, wait for the download to complete
let scrape = async () => {
const browser = await puppeteer.launch({headless:true, ignoreHTTPSErrors: false, userDataDir: "./download", slowMo: 100}); // , dumpio: true, , executablePath: '/usr/bin/google-chrome-stable'
const page = await browser.newPage();
await page.goto('http://learningphp.example.com/openlink.php', {waitUntil: 'networkidle2'});
//await page._client.send('Page.setDownloadBehavior', {behavior: 'allow', downloadPath: './'})
await page.click('body > button');
await page.waitFor(10 * 1000);
let result = {key: 'ok'};
browser.close();
return result;
};
scrape().then((value) => {
console.log(value); // Success!
});
openlink.php
<?php
<button id="link" class="downloadLink">
Download it!
</button>
<script type="text/javascript">
document.getElementById("link").addEventListener("click", function(){
window.open("download.php",'_blank');
});
</script>
download.php
<?php
ob_start();
$file = "sample.pdf";
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();
}
I can download pdf file if headless is false
I already found many questions here in SO about the theme, but any of them helps me with a specific problem.
I need to send a ajax request to PHP and then download a PDF file.
This is my Javascript
$('body').on("click",'.download-file', function(e) {
e.stopPropagation();
var id = $(this).attr('data-id');
$.ajax({
url: 'app/myPage/download',// The framework will redirect it to index.php and then to myPage.class and method dowload
data: id,
type: 'POST',
success: function (return) {
console.log(return);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log("Error... " + textStatus + " " + errorThrown);
}
});
});
Here is my PHP file:
class myPage{
public function download()
{
$id = $_POST['id'];
$filePath = $this->methodToGetFile($id);
$name = end(explode('/',$filePath));
$fp = fopen($filePath, 'rb');
header("Cache-Control: ");
header("Pragma: ");
header("Content-Type: application/octet-stream");
header("Content-Length: " . filesize($filePath));
header("Content-Disposition: attachment; filename='".$name."';");
header("Content-Transfer-Encoding: binary\n");
fpassthru($fp);
exit;
}
}
With this approach, I have the PDF "printed" in the console like
%PDF-1.5%����1 0 obj<</Type/Catalog/Pages 2 0 R/Lang(pt-BR) /StructTreeRoot 8 0 R/MarkInfo<</Marked true>>>> ....
So, I'd like to know what should I do to open this file and download it.
In the linked questions I see something about window.location, but I don't know how can I use it.
I've already tried change the PHP headers to try force the download, but no success with it. In these cases I just receive null in the javascript nothing happens. Here are the modified headers:
header('Content-Type: application/pdf');//tried with this option
//header('Content-Type: application/octet-stream');// also tried with this other option
header('Content-Disposition: attachment; filename=' . $name);
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($filePath));
Are there some good approach to do this?
i don't think this approach to downloading a pdf will work. Javascript is sending the request, and php is sending the response. You want the response to go directly to the browser, not to javascript. You should change the download link to go directly to the download location. No ajax / javascript needed. Like this:
download
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'm trying to save canvas as a image file ,users get to determine which image format to download (png or jpg), then force download the file without storing the file on the server.
This is what I got so far:
JS Script:
$.ajax(
{
type : "POST",
url : "../php/download_image.php",
data:
{
format: 'png',
dataURL: flattenCanvas.toDataURL('image/png')
}
});
PHP:
$data = $_POST['dataURL'];
$format = $_POST['format'];
$file = $file = md5(uniqid()) . '.'.$format;
$uri = substr($data,strpos($data,",")+1);
file_put_contents($file, base64_decode($uri));
if($format == 'png')
{
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: image/png');
header('Content-Disposition: attachment; filename='.basename($file));
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));
readfile($file);
exit;
}
else {
echo "$file not found";
}
}
The code cannot force download and I have no idea why it is not working.
Any help greatly appreciated.
If you don't want to store the file on the server, you don't need to interact with the server in any way. Just let the user download the content of the canvas as described here.