In my project site, if I click on a link, the PDF opens in a new or parent window. Well I want a box to appear that prompts the user to download the file instead of opening it.
Does anyone know of a simple JavaScript onClick event that will do this, in all browsers, with default settings?
My server is PHP based.
Since your edit states that you're using PHP, here's how to do the same in PHP:
<?php
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="downloaded.pdf"');
readfile('original.pdf');
?>
Since you've tagged it .NET, I'd say this is your best solution:
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment;filename=download.pdf");
Response.WriteFile(Server.MapPath("~/files/myFile.pdf"));
Response.Flush();
Response.Close();
Change the Content-Type to application/octet-stream. You may find however, that some browsers will infer from the file extension that it should open as a PDF with your favorite PDF viewer.
Response.ContentType = "application/octet-stream";
Also, set the following:
Response.AppendHeader( "content-disposition", "attachment; filename=" + name );
You can't do it via javascript, you need server side implementation.
Here's the SO Post which should help:
Allowing user to download from my site through Response.WriteFile()
http://aspalliance.com/259_Downloading_Files__Forcing_the_File_Download_Dialog
If you are getting a corrupted file error try this:
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private', false);
header('Content-Type: application/pdf');
header('Content-disposition: attachment; filename=' . basename($file));
header("Content-Transfer-Encoding: binary");
header('Content-Length: ' . filesize($file)); // provide file size
header('Connection: close');
readfile($file);
Where $file is the full path or url of the file.
Related
I want to give a file to a person based on the users rank so I need to hide the files in a directory which is hidden.
I'm using Plesk and my structure looks like this:
api (reachable from https://api.pexlab.net)
cloud (reachable from https://cloud.pexlab.net)
default (reachable from https://pexlab.net)
error_docs
hidden (not reachable)
My PHP script is located in:
api/hub/Test.php (reachable from https://api.pexlab.net/hub/Test.php)
I have tried this:
# In Test.php
downloadFile("../../hidden/hub/download/assets/user/main.fxml");
# Function:
function downloadFile($file) {
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, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
}
This method works but I want to redirect to this file (show it) and NOT download it. So I have tried using this:
header("Location: ../../hidden/hub/download/assets/user/main.fxml");
But this tried to redirect to https://api.pexlab.net/hidden/hub/download/assets/user/main.fxml which is invalid.
The only difference between "viewing" and "downloading" a file is what the browser does with the data. Ultimately, that's in the hands of the user, but the server can indicate what it would like to happen.
I suspect you have copied these lines without really understanding what they do:
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, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
These are all instructions to the browser telling it what to do with the data you send.
The Content-Disposition header is used to tell the browser "rather than trying to display this content straight away, suggest the user saves it in a file, with this name". To use the browser's default behaviour, you would simply leave off this header, or give it the value inline.
The Content-Type header tells the browser what type of file this is. The value application/octet-stream means "just a bunch of bytes, don't try to interpret them in any way". Obviously, that would be no good for viewing a file in the browser, so you should send an appropriate "MIME type", like text/html or image/jpeg, as appropriate for the file you're serving. I'm guessing "FXML" is an XML-based format, so text/xml might be appropriate; or if it's human readable and you just want it displayed without any formatting, use text/plain.
Im trying to workout if i can stream PDF files from behind the web root via an image/pdf viewer. Google's documentation says to embed a PDF in an HTML page you just use html and include an embed and point to the file.
http://docs.google.com/viewer?url=YourDocumentUrlHere
However for the purposes of security I am using a document/image script that streams the file to the browser and therefore the filepath remains hidden from the view of the user and unable to be accessed by google documents.
The output sent by the document image script is in the form
header('Content-type: application/pdf');
readfile("/home/******/*****/images/enquiries/23251/23251-1.pdf");
can anyone help me with this?
JUST IN CASE ANYONE WAS WONDERING... i added this to the image server script (imageserve.php)
if ($type = "application/pdf") {
header('Content-Description: File Transfer');
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
} else
and then on the page where i wanted to display the pdf i added
$temp = "home/..../..../development/imageserve.php?filename=xxxxxx";
<embed style="width:1200px; height:730px;" name="plugin" src="$temp" type="application/pdf">
I'm using PHP to generate a PDF via browser for my web-application. Recently, the client changed the webserver to Apache and now this feature is no longer working. Instead of generating the PDF, the browser is showing the PDF as text, just as it was ignoring Content-Type (that is set to "application/pdf"). In fact, I successfully simulated the problem by commenting the line setting the Content-Type in the source code.
I need ideas about where and what to look for, any help will be very welcome :)
Since you generate PDF files through PHP, you can try to add these headers:
$file_default = 'default filename you want to appear when the user downloads.pdf';
$file_location = '/path/to/file.pdf';
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.$file_default);
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file_location));
ob_clean();
flush();
readfile($file_location);
I guess you'd have to force apache to download PDF content rather than showing:
check this: http://www.thingy-ma-jig.co.uk/blog/06-08-2007/force-a-pdf-to-download
I have an excel file that i want a user to be able to download from my server. I have looked at a lot of questions on here but i cannot find a way to correctly download the file w/o corruption. I am assuming it is the headers but i haven't had a working combination of them yet. This is what i have right now and in the corrupt file that i receive i can see the column names of the spreadsheet i want but its all messed up.
$filename = '/var/www/web1/web/public/temporary/Spreadsheet.xls';
header("Content-type: application/octet-stream");
header("Content-type: application/vnd-ms-excel");
header("Content-Disposition: attachment; filename=ExcelFile.xls;");
header("Pragma: no-cache");
header("Expires: 0");
readfile($filename);
edit: Solution I forgot to add that i was using Zend and it was corrupting the files when trying to use native php methods. My finsihed code was to place a link to another action in my controller and have the files download from there
public function downloadAction(){
$file = '/var/www/web1/web/public/temporary/Spreadsheet.xls';
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment; filename="Spreadsheet.xls"');
readfile($file);
// disable the view ... and perhaps the layout
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
}
try doing it this way
ob_get_clean();
echo file_get_contents($filename);
ob_end_flush();
For one, only specify Content-Type once. You can use the excel-specific header but the generic application/octet-stream may be a safer bet just to get it working (the real difference will be what the browser shows the user with regards to "what would you like to open this file with", but basic browsers can rely on the extension as well)
Also, make sure you specify Content-Length and dump the size (in bytes) of the file you're outputting. The browser needs to know how big the file is and how much content it's expecting to receive (so it doesn't stop in the middle or a hiccup doesn't interrupt the file download).
So, the entire file should consist of:
<?php
$filename = '/var/www/web1/web/public/temporary/Spreadsheet.xls';
header("Content-Disposition: attachment; filename=ExcelFile.xls;");
header('Content-Type: application/octet-stream');
header('Content-Length: ' . filesize($filename));
header("Pragma: no-cache");
header("Expires: 0");
#readfile($filename);
$file_name = "file.xlsx";
// first, get MIME information from the file
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $file_name);
finfo_close($finfo);
// send header information to browser
header('Content-Type: '.$mime);
header('Content-Disposition: attachment; filename="download_file_name.xlsx"');
header('Content-Length: ' . filesize($file_name));
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
//stream file
ob_get_clean();
echo file_get_contents($file_name);
ob_end_flush();
This concerns downloading files with PHP
My php version is 5.3.5 and my apache is 2.2.17
I am trying to dowload files (pdf,jpg,tiff) that I have uploaded in my server, and they download with the same size and type but I can not see them. I am guessing they are not copied right. But when I open the original uploaded ones they work just fine.
I have seen almost all the questions that appeared as suggested and none of them answered the question, te only similar one is this, but still doesnt answer my question.
to download I am using this code
header("Content-type: application/force-download");
header('Content-Disposition: inline; filename="' . $dir . '"');
header("Content-Transfer-Encoding: Binary");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Content-length: ".filesize($dir));
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $file . '"');
readfile("$dir");
where $dir="62756d616769636e63/646973736572746174/ehddggh/1.JPG"
and $file="1.JPG"
can anyone give me a hint on what I am doing wrong, or give me a better solution to download files?
This smells like you are getting extra (spurious) content in your downloaded files.
Make sure you have no BOM headers, spaces, or anything else before your PHP open tags in your files; also, that you have no trailing whitespace or any other data after the closing PHP tags (if you close your PHP tags).
Also, clean up your code a bit: why multiple Content-Type headers? Why multiple Content-Disposition headers?
readfile($dir); // without the quotes?
Also, make sure that $dir actually exists
is_file($dir) or file_exists($dir)
Thank you all for the answers. I was calling the download as a function in a file with other functions in it so in the end I had to write a script alone, apart from other files. My problem was that I needed it to be safe and to only download a file if it belonged to the user and the user was logged in, so I send all the data I need, ciphered and inside the script I use a series of things to see if the owner is really the logged user. So if anyone wants to know this is the code I used and works perfectly.
<?php
session_start();
$a=$_GET['a'];
$parts=explode("-",$a);
$tres=$parts[0];
$nombre=$partes[1];
$dbcodletra=substr($tres,2);
if($dbcod!=$_SESSION["username"])$boolt=0;
if($ext==1) $extl=".jpg";
if($ext==2) $extl=".jpeg";
if($ext==3) $extl=".tif";
if($ext==4) $extl=".tiff";
if($ext==5) $extl=".pdf";
if($ext==6) $extl=".doc";
if($ext==7) $extl=".docx";
if($tipoproy==1) $dir="rute/".$dbcodletra."/".$nombre.$extl;
if($tipoproy==2) $dir="rute/".$dbcodletra."/".$nombre.$extl;
if($tipoproy==3) $dir="rute/".$dbcodletra."/".$nombre.$extl;
if($tipoproy==4) $dir="rute/".$dbcodletra."/".$nombre.$extl;
if (file_exists($dir) && $boolt) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($dir));
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($dir));
ob_clean();
flush();
readfile($dir);
exit;
}else echo "<meta http-equiv=\"Refresh\" content=\"0;url=misdocumentos.php\">";
?>
Paying it forward on a two-year old question...
I had a similar issue with corrupt downloads that could not be opened (when right-click & save-as worked perfectly). After reading #Jon's answer, I figured he was on to something. If you look at the docs for readfile (linked below), you will see an ob_clean(), a flush(), and an exit in their example. All of those will minimize leakage of extra character data in the response. I just copied their Example #1 and my problem was solved.
http://php.net/readfile
Your headers look messy, try just doing this:
header('Pragma: public');
header('Cache-Control: public, no-cache');
header('Content-Type: application/octet-stream');
header('Content-Length: ' . filesize($dir));
header('Content-Disposition: attachment; filename="' . basename($dir) . '"');
header('Content-Transfer-Encoding: binary');
readfile($dir);