I have a simple PHP page for downloading files that contains this code.
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $name . '"');
readfile("$file");
This downloads the current bit of music I am listening to in a simple flash player.
For some reason in the latest Safari 4.0
When the download code is executed it interrupts the loading of the song to the flash player.
Basically it makes the flash player act as if it has reached the end of the file and loaded it all.
Kinda hacky, but you could embed a hidden iframe on the page and make the download link use that (href="download.php?filename=something" target="iframe_name"). Like I said, a bit lame, but it (theoretically) would do the trick since you're not redirecting the page technically.
Related
I've made a small program to search and display an PDF-file, some years ago. The PDF-file is shown inline, so the user can verify that it is the correct file. Usually he then uses the download button of the adobe plugin to save the file on his PC.
Since end of may this makes problems with Microsoft Edge and Google Chrome. The file is displayed correctly and when the user clicks the download button the save dialog opens, but when he presses the save button the file is not downloaded (error message "network error"). Strange thing is, that the print button next to the download button works.
On Firefox the whole thing still works. Each browser is updated automatically.
This is the code I use to display the pdf file:
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="' . $deliveryPdf->getFilename() . '"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
echo $deliveryPdf->getData();
Some notes, I recognized while analyzing the problem:
On Edge and Chrome the save dialog does not use the filename given in the response headers, while firefox uses the correct name
When using the "download" or "print" button in the adobe view, there is no additional request to the webserver (on none of the browsers). The only request on the webserver appears when initially opening the pdf
The print button works fine on all browsers. This raises the question where the difference between download and print is, when they both seem to use the cached file.
I'm using this bit of code to download a file (path_facture_name) from the server to the client browser :
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($path_facture_name) . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Content-Length: ' . filesize($path_facture_name));
ob_clean();
flush();
readfile($path_facture_name);
ob_end_flush();
# ----
# Some other PHP code
# ----
This works just fine, but when the file is downloaded, the script is ended, and the part Some other PHP code will never be executed.
So, my question is, is there a better way to download a file from the server that don't abort the execution of the next part of the code ?
I've tried to use <iframe> or JavaScript code to redirect the window to a sipparate .php file that will handle the download. But that didn't work because this feature that I wanna add is a part of an 18 years old complex php CRM that I can't easily/freely edit.
I'm looking for a PHP solution or guidelines.
Before submitting the form (or whatever takes you to the download page) use javascript to display sg. like "File downloading, press ok" and a button. It will stay because there's no HTML content to be loaded.
Set this button to load your download page again but skipping the file download headers this time (with a get switch).
The answer for this question is #ADyson's comment above :
« "and reload the current php page"...you can't do that, only the browser can do that in this situation. You've already given your response to the request in the form of a file download. The only way to "reload the current page" from the server would be to send some new HTML for the browser to display. But you can't respond to a single HTTP request with both a file download and a HTML document. It's physically impossible. You've already set headers indicating to the browser that the response is a file for download. »
So this is a HTTP limitation. We can't do a multi-part response.
I have a script that merges 2 documents and then it shows a final document in a browser.
It works in Firefox, Opera and IE. But it does not work in Chrome.
Chrome only shows loading and it stops in 1/4 of loading.
The code:
exec("pdftk A=$pdfin B=$tmpfname cat B1 A output $tmpfoutput");
$data = file_get_contents($tmpfoutput);
header("Content-type: application/pdf");
header("Content-disposition: inline;filename=GeneratedPdf.pdf");
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($tmpfoutput));
header('Accept-Ranges: bytes');
echo $data;
I have been told that it also worked in Chrome before so I think there will be only a problem with the last version.
Thanks for any help.
By appending Accept-Ranges: bytes, your script tells the browser that it will accept range requests, i.e. multiple requests that request a part of the response. Your script obviously does not support range requests because it generates and provides the data at once.
To fix the error, remove header('Accept-Ranges: bytes');
If your PDF files are usually large, then a more user-friendly solution is to actually implement range requests in your script. Odds are that your server does already have an efficient routine that handles range requests, so a smart choice is to save PDF file to a publicly accessible directory, then 302-redirect the request to this URL after the PDF has been generated. Make sure that the URLs are unguessable, e.g. by using UUIDs. And remove the PDF files at some point, e.g. using a cronjob.
I would like to display a PDF file as a result of browsing to the following address:
http://www.mydomain.com/myfile
To that end I am using a 301 Redirect on .htaccess which redirects myfile to myfile.php. This file then contains
<?php
$filename = 'files/somefile.pdf';
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="somefile.pdf"');
header('Content-Length: ' . filesize($filename));
#readfile($filename);
?>
The main idea is that the PDF is displayed in the browser without prompting the user for download, but that when forcing the download the output filename becomes somefile.pdf. Everything is working smoothly in IE, Firefox, Chrome, Safari and Opera. However, in Android nothing happens. The PDF is not displayed and it doesn't prompt for download. How can I get this to work with Android? Is there anything I need to change in the script?
Android native browser doesn't have PDF support. You will need to embed the your url with google doc. Try this one..hope it will help..
url="http://docs.google.com/gview?embedded=true&url=http://118.102.182.50/victor/testpdf.aspx?s=9";
webView.loadUrl(url);
test.php code:
$path = 'audio.mp3';
header("Content-type: audio/mpeg");
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: inline; filename="'.$path.'"');
header("Content-length: ".filesize($path));
readfile($path);
html code:
<iframe src="test.php"></iframe>
this will play the .php as a .mp3, but i will not be able to access the navigation slider in the browser media player. i click on the slider in several different places, but nothing will happen. when i change the source to "audio.mp3" i am able to control the slider again. im pretty sure that it has something to do with the headers. any idea what headers i can use to fix this?
It actually has everything to do with what browser and plugin you are using, "streaming" mp3 or media files for that matter should not be done this way. Use any of the many open source and easy to use Flash players, they handle buffering, controls, display/hidden, and everything for you, for a mp3 file on your server.