In public/templates/calendar.html I have
<a href="" id="secret_download_button" style="display:none" download="">
In the same file I have a button (download qr), i make an ajax call from javascript, the qr gets created in /public/uploads/thumbs/qrcodes/'filename'
the ajax calls is finished and the following function is called which is in
public/javascript/some.js
function (data) {
$('#secret_download_button').attr('href',data.content);
$('#secret_download_button').attr('download','somename');
$('#secret_download_button').click();
});
data.content = public/upload/thumbs/qrcodes/someqr.png (example)
I need to use relative paths, not absolute paths. What am I doing wrong ? I am guessing that I am setting the href path wrong.
Also from what I read online this solution is not supported by IE. Is there another, simpler, more elegant way of doing this ( I need to be able to specify the name of the file which will be downloaded )
Edit
Solved it server-side in the end. thanks. For anyone else having the same problem I used this:
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($activity_name . '.png').'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($root . $path . $file_name));
readfile($root . $path . $file_name);
exit;
You're right, the download attribute is not supported by IE nor Edge (supported in Edge 13+) : http://caniuse.com/#feat=download
To have a cross-browser solution, you will have to open the url in the current window :
function (data) {
window.location.href = data.content;
});
or a new window :
function (data) {
window.open(data.content);
});
Two limitations:
you can't set the filename client-side, you have to set it server side
the browser will not download the file if it can read it (like images, pdf...), you will have to use the "save as"
Related
I have this code below. I am taking an existing excel called b1b5.xls and i am putting some values as you can see.. The problem is that i don't know how to assosiate a button that when i click it, the b1b5.xls is been downloaded with my values..
<html>
<head>
</head>
<body>
<center>
<button onclick=" somefunction ?? ">Download!</button>
</center>
</body>
</html>
<?php
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\IOFactory;
$spreadsheet = IOFactory::load('b1b5.xls');
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('C7', 'Myvalue');
$sheet->setCellValue('C8', 'Myvalue2');
foreach (range('A', 'E') as $col) {
$sheet->getColumnDimension($col)->setAutoSize(true);
}
$filename = 'trapezas_ellados.xlsx';
// Redirect output to a client's web browser (Xlsx)
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="' . $filename . '"');
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
header('Cache-Control: max-age=1');
// If you're serving to IE over SSL, then the following may be needed
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header('Pragma: public'); // HTTP/1.
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save('php://output');
?>
You can use the download attribute in anchor tag. It can contain extensions like .img, .pdf, .txt, .html, etc.
Here is an example
<a href="/images/myw3schoolsimage.jpg" download>
Put the php code in another page and make the download in side form with method post .
in the page_with_code_to_generate_the_excel.php
if(isset($_POST){ ..PUT THE PHP CODE HERE}
that's how I did it it work every time, I hope my answer helped you ^_^
First, you wanna separate your HTML and PHP Script.
In your HTML link to your PHP Script processing the excel file and send the correct headers for forcing the file to download, see this Stackoverflow question:
Force file download with php using header() - by User: Kerp
So this is my whole setup :
I'm on a HTML page and i'm opening a POST request using JS inside the same HTML page and i'm opening it in a new window like this :
<script>
function Download() {
form = document.createElement('form');
form.setAttribute('method', 'POST');
form.setAttribute('action', 'test.php?App=AppNameHere');
form.setAttribute('target', 'NewWindow');
myvar = document.createElement('input');
myvar.setAttribute('name', 'terms');
myvar.setAttribute('value', '');
form.appendChild(myvar);
document.body.appendChild(form);
window.open('test.html', 'NewWindow', 'scrollbars=no,menubar=no,height=100,width=500,resizable=no,toolbar=no,status=no');
form.submit();
}
</script>
Now inside test.php i'm downloading an app referring to the GET request for the App var in the URL, also the POST request works just fine, but after start downloading the file i need to close the window, so i used :
echo "<script type='text/javascript'>window.close();</script>";
Now i tested it and it worked closing the window just fine, but now here is my problem... inside the test.php file i'm also using sessions (session_start();) and when i do use that line (session_start();) the java script code for closing the window does not work any more!!, i'v tried commenting all the code but keeping session_start(); and i really found out that it's what preventing the window from closing, which is very weird, they are not related at all, or this is what i think at least, here is my test.php file :
<?php
session_start();
if($_SESSION["TEMP"] == "Yes"){
if(isset($_GET['App'])){
$fileName = $_GET['App'] . " - Setup.exe";
if(basename($_GET['App']) == $_GET['App']){
$path = 'download_directory/' . $fileName;
$size = filesize($path);
header('Content-Type: application/octet-stream');
header('Content-Length: ' . $size);
header('Content-Disposition: attachment; filename=' . $fileName);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
ob_clean();
$file = # fopen($path, 'rb');
if($file){
fpassthru($file);
$_SESSION["TEMP"] = "No";
}
}
}
}
echo "<script type='text/javascript'>window.close();</script>";
?>
Downloading the file also worked!
Can someone please explain to me what's happening and help me go around this because i really need to use sessions?!
Let's say i want to generate a download link and put it into <a> tag.
my php script:
function download_link(){
$this_id = "d"; //this is the name of file from server
$original_filename = 'xample.pdf'; //This come from database
$ext = pathinfo($original_filename, PATHINFO_EXTENSION);
$file = '../uploads/'.$this_id.'.'.$ext;
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/'.$ext);
header('Content-Disposition: attachment; filename='.$original_filename);//Rename the file with its original filename
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
return readfile($file);//Here where i want to return the generated url
}
return '#'; //Or return nothing if file doesn't exist
echo ''; //And put it here, the generated url
now, my directory location is ../uploads/.
i am expecting a result like: so when the user click this tag the file will be downloaded. but instead, when i reload the page it is automatically downloading without clicking the download button which is the <a> tag.
note: i am trying to rename the filename when botton download is clicked.
i know there is a problem in my logic. maybe this can be done with JQUERY? or AJAX? im searching for solution but did not find the answer.
here's what i did with JQUERY AJAX:
HTML tag
<a id="server_name_file_name">download</a>
JQUERY AJAX:
$('a').click(function(e) {
e.preventDefault();
var id = $(this).attr('id');
$.ajax({
type: 'POST',
url: 'download.php',
data: { server_file_name: id,},
success: function(response) {
if(response == 1){
alert("Unable to download, Maybe the file is corrupted. Please try to reload the page.");
}else{
window.location.href = response;
return false;
}
}})
});
download.php
$this_id = $_POST['server_file_name'];
$original_filename = 'xample.pdf'; //This come from database
$ext = pathinfo($original_filename, PATHINFO_EXTENSION);
$file = '../uploads/'.$this_id.'.'.$ext;
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/'.$ext);
header('Content-Disposition: attachment; filename='.$original_filename);//Rename the file with its original filename
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
echo readfile($file);//Here where i want to return the generated url
exit();
} die('1');
but doesnt work.
anyone can help me here? Thank you!!!!
You're returning the actual contents of the file with readfile.
Thats why browser starts to download the file you return.
What you need to do is to generate the string which will point to the file.
If your "uploads" dir is accessible by url, then your downloads.php should look like this:
$this_id = $_POST['server_file_name'];
$original_filename = 'xample.pdf'; //This come from database
$ext = pathinfo($original_filename, PATHINFO_EXTENSION);
$file = '../uploads/' . $this_id . '.' . $ext;
if (file_exists($file)) {
echo 'www.myserver.com/uploads/' . $this_id . '.' . $ext;
exit();
}
die('1');
If your uploads dir is not accessible from outside, then you need to copy the file into the public directory first.
At a first glance, i can identify a couple of problems.
Your download function does not return the link of the file but rather it outputs the file itself, so it is logical that when refreshing the page, the file is downloading.
Plus, I can see that you are calling your function useing function download_link() whereas it should be directly download_link().
The proper way this should be done is having the download link to a file executing the download_link function (ex: http://yoursite.com/download_file.php?file=filename)
Of course it is advisable to have an id instead of filename in the URL and apply all the security you need etc...
Inside download_file.php file, you can call download_link($filename) or better download_link($id) and get the file name from the database or wherever you are storing it and then output the file as you are doing now.
I have a page with some forms and input fields, which the user fills in and then they are sent to a php page via Ajax and $_POST.
And then the php File writes the output to a txt file. - that works just fine. My problem is I am trying to force the user to download it on that same page that creates the file, after the file is created and I can't seem to get it to work, nothing happens besides the file being created:
Here the code where the .txt File is created (this works nice):
$myfile = fopen("test.txt", "w") or die("Unable to open file!");
foreach ($URLsArray as &$url) {
$row=$SomeArray[$keys[$index]]."\t".$SomeArray[$keys[$index]]."\t".$SomeArray[$keys[$index]]."\t".$SomeArray[$keys[$index]]."\t".$url."\n";
fwrite($myfile, $zeile);
$index = $index + 1;
}
fclose($myfile);
And here the code, where I try to force the download: (after the fclose)
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename('test.txt'));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize('test.txt'));
readfile('test.txt');
exit;
And when I try this I get the error: "Unexpected token A". "A" is the first letter in the test.txt, which is created.
And I know that there are a lot of similar questions, but not one solution worked for me.
I hope someone can help me :)
Instead of doing this backend with PHP you could try to do this on the frontend part. The easiest solution is to write some JavaScript code which adds an iframe to your webpage. The iframe should then have a href to the file you want the user to download.
Okay here my solution: #CBroe thanks for the hint with the background request, I would have tried for ages to get the download work in the php file. So what I did:
In PHP: I echo the filename after the .txt file is created:
echo json_encode(array('filename' => "your_Data".time().".txt"));
Than in JavaScript I read the filename in the success method and put the link in an <a> element. Later that will be a button which is set active.
success : function(data) {
$("#button_get_file_download").attr("href", "urlToFolder"+data.filename);
},
I have built a PHP script that sends *.MP3 files form outside the public_html directory,
it works OK and sends the file. The problem is that I have a JavaScript script which should change the current time of the audio file (audioFile.currentTime = 25;).
When I do this(Get the file from inside the public_html directory), it works:
// JavaScript:
var audioFile = new Audio("https://www.website.com/files/audioFile.mp3");
audioFile.play();
audioFile.currentTime = 15;
But, when I try to get the file from the following PHP script it sends the file OK. But, I can't change the "currentTime" using JavaScript
<?php
// This PHP file is public www.website.com/getAudioFile.php/
$fileLocation = "../audioFiles/audioFile.mp3";
if (file_exists($fileLocation))
{
header('Content-type: audio/mpeg');
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
readfile($file);
}
?>
This is the JavaScript within which I tried to change the audio file currentTime:
<script>
var audioFile = new Audio("www.website.com/getAudioFile.php");
audioFile.play();
audioFile.currentTime = 15;
</script>
Each time I use object.currentTime = 15, the audio files plays from the start.
If anyone knows what headers I should send or anything else I should do, please let me know how to solve my problem.
Maybe You should bind canplay event from Audio component and in this callback set currentTime property.
http://www.w3schools.com/tags/av_event_canplay.asp
Shortly after I have posted this question, I found the solution to the problem.
In order to make the script work you will need to add the header('Accept-Ranges: bytes');
Like this:
<?php
// This PHP file is public www.website.com/getAudioFile.php/
$fileLocation = "../audioFiles/audioFile.mp3";
if (file_exists($fileLocation))
{
header('Content-type: audio/mpeg');
header('Content-Disposition: inline; filename="' . $filename . '"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
header('Content-Length: ' . filesize($file));
readfile($file);
}
?>