I am giving link of a pdf file on my web page for download, like below
<a href="myfile.pdf">Download Brochure</a>
The problem is when user clicks on this link then
But I want it always pop-up to the user for download, irrespective of "Adobe acrobat" is installed or not.
Please tell me how i can do this?
This is the key:
header("Content-Type: application/octet-stream");
Content-type application/x-pdf-document or application/pdf is sent while sending PDF file. Adobe Reader usually sets the handler for this MIME type so browser will pass the document to Adobe Reader when any of PDF MIME types is received.
This can be achieved using HTML.
<a href="myfile.pdf">Download Brochure</a>
Add download attribute to it: Here the file name will be myfile.pdf
<a href="myfile.pdf" download>Download Brochure</a>
Specify a value for the download attribute:
<a href="myfile.pdf" download="Brochure">Download Brochure</a>
Here the file name will be Brochure.pdf
I solved mine using the whole url of the PDF file (Instead of just putting the file name or location to href): a href="domain . com/pdf/filename.pdf"
Don't loop through every file line. Use readfile instead, its faster. This is off the php site: http://php.net/manual/en/function.readfile.php
$file = $_GET["file"];
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header("Content-Type: application/force-download");
header('Content-Disposition: attachment; filename=' . urlencode(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;
}
Make sure to sanitize your get variable as someone could download some php files...
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>File Uploader</title>
<script src="../Script/angular1.3.8.js"></script>
<script src="../Script/angular-route.js"></script>
<script src="../UserScript/MyApp.js"></script>
<script src="../UserScript/FileUploder.js"></script>
<>
.percent {
position: absolute;
width: 300px;
height: 14px;
z-index: 1;
text-align: center;
font-size: 0.8em;
color: white;
}
.progress-bar {
width: 300px;
height: 14px;
border-radius: 10px;
border: 1px solid #CCC;
background-image: -webkit-gradient(linear, left top, left bottom, from(#6666cc), to(#4b4b95));
border-image: initial;
}
.uploaded {
padding: 0;
height: 14px;
border-radius: 10px;
background-image: -webkit-gradient(linear, left top, left bottom, from(#66cc00), to(#4b9500));
border-image: initial;
}
</>
</head>
<body ng-app="MyApp" ng-controller="FileUploder">
<div>
<table ="width:100%;border:solid;">
<tr>
<td>Select File</td>
<td>
<input type="file" ng-model-instant id="fileToUpload" onchange="angular.element(this).scope().setFiles(this)" />
</td>
</tr>
<tr>
<td>File Size</td>
<td>
<div ng-repeat="file in files.slice(0)">
<span ng-switch="file.size > 1024*1024">
<span ng-switch-when="true">{{file.size / 1024 / 1024 | number:2}} MB</span>
<span ng-switch-default>{{file.size / 1024 | number:2}} kB</span>
</span>
</div>
</td>
</tr>
<tr>
<td>
File Attach Status
</td>
<td>{{AttachStatus}}</td>
</tr>
<tr>
<td>
<input type="button" value="Upload" ng-click="fnUpload();" />
</td>
<td>
<input type="button" value="DownLoad" ng-click="fnDownLoad();" />
</td>
</tr>
</table>
</div>
</body>
</html>
I found a way to do it with plain old HTML and JavaScript/jQuery that degrades gracefully. Tested in IE7-10, Safari, Chrome, and FF:
HTML for download link:
<p>Thanks for downloading! If your download doesn't start shortly,
<a id="downloadLink" href="...yourpdf.pdf" target="_blank"
type="application/octet-stream" download="yourpdf.pdf">click here</a>.</p>
jQuery (pure JavaScript code would be more verbose) that simulates clicking on link after a small delay:
var delay = 3000;
window.setTimeout(function(){$('#downloadLink')[0].click();},delay);
To make this more robust you could add HTML5 feature detection and if it's not there then use window.open()
to open a new window with the file.
Try this:
<a href="pdf_server_with_path.php?file=pdffilename&path=http://myurl.com/mypath/">Download my eBook</a>
The code inside pdf_server_with_path.php is:
header("Content-Type: application/octet-stream");
$file = $_GET["file"] .".pdf";
$path = $_GET["path"];
$fullfile = $path.$file;
header("Content-Disposition: attachment; filename=" . Urlencode($file));
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . Filesize($fullfile));
flush(); // this doesn't really matter.
$fp = fopen($fullfile, "r");
while (!feof($fp))
{
echo fread($fp, 65536);
flush(); // this is essential for large downloads
}
fclose($fp);
Don't loop through every file line. Use readfile instead, its faster. This is off the php site: http://php.net/manual/en/function.readfile.php
$file = $_GET["file"];
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header("Content-Type: application/force-download");
header('Content-Disposition: attachment; filename=' . urlencode(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;
}
Make sure to sanitize your get variable as someone could download some php files...
if you need to limit download rate, use this code !!
<?php
$local_file = 'file.zip';
$download_file = 'name.zip';
// set the download rate limit (=> 20,5 kb/s)
$download_rate = 20.5;
if(file_exists($local_file) && is_file($local_file))
{
header('Cache-control: private');
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($local_file));
header('Content-Disposition: filename='.$download_file);
flush();
$file = fopen($local_file, "r");
while(!feof($file))
{
// send the current file part to the browser
print fread($file, round($download_rate * 1024));
// flush the content to the browser
flush();
// sleep one second
sleep(1);
}
fclose($file);}
else {
die('Error: The file '.$local_file.' does not exist!');
}
?>
For more information click here
In a Ruby on Rails application (especially with something like the Prawn gem and the Prawnto Rails plugin), you can accomplish this a little more simply than a full on script (like the previous PHP example).
In your controller:
def index
respond_to do |format|
format.html # Your HTML view
format.pdf { render :layout => false }
end
end
The render :layout => false part tells the browser to open up the "Would you like to download this file?" prompt instead of attempting to render the PDF. Then you would be able to link to the file normally: http://mysite.com/myawesomepdf.pdf
This can be achieved using HTML.
<a href="myfile.pdf">Download Brochure</a>
Add download attribute to it: Here the file name will be myfile.pdf
<a href="myfile.pdf" download>Download Brochure</a>
Specify a value for the download attribute:
<a href="myfile.pdf" download="Brochure">Download Brochure</a>
Here the file name will be Brochure.pdf
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>File Uploader</title>
<script src="../Script/angular1.3.8.js"></script>
<script src="../Script/angular-route.js"></script>
<script src="../UserScript/MyApp.js"></script>
<script src="../UserScript/FileUploder.js"></script>
<>
.percent {
position: absolute;
width: 300px;
height: 14px;
z-index: 1;
text-align: center;
font-size: 0.8em;
color: white;
}
.progress-bar {
width: 300px;
height: 14px;
border-radius: 10px;
border: 1px solid #CCC;
background-image: -webkit-gradient(linear, left top, left bottom, from(#6666cc), to(#4b4b95));
border-image: initial;
}
.uploaded {
padding: 0;
height: 14px;
border-radius: 10px;
background-image: -webkit-gradient(linear, left top, left bottom, from(#66cc00), to(#4b9500));
border-image: initial;
}
</>
</head>
<body ng-app="MyApp" ng-controller="FileUploder">
<div>
<table ="width:100%;border:solid;">
<tr>
<td>Select File</td>
<td>
<input type="file" ng-model-instant id="fileToUpload" onchange="angular.element(this).scope().setFiles(this)" />
</td>
</tr>
<tr>
<td>File Size</td>
<td>
<div ng-repeat="file in files.slice(0)">
<span ng-switch="file.size > 1024*1024">
<span ng-switch-when="true">{{file.size / 1024 / 1024 | number:2}} MB</span>
<span ng-switch-default>{{file.size / 1024 | number:2}} kB</span>
</span>
</div>
</td>
</tr>
<tr>
<td>
File Attach Status
</td>
<td>{{AttachStatus}}</td>
</tr>
<tr>
<td>
<input type="button" value="Upload" ng-click="fnUpload();" />
</td>
<td>
<input type="button" value="DownLoad" ng-click="fnDownLoad();" />
</td>
</tr>
</table>
</div>
</body>
</html>
This is the key:
header("Content-Type: application/octet-stream");
Content-type application/x-pdf-document or application/pdf is sent while sending PDF file. Adobe Reader usually sets the handler for this MIME type so browser will pass the document to Adobe Reader when any of PDF MIME types is received.
In a Ruby on Rails application (especially with something like the Prawn gem and the Prawnto Rails plugin), you can accomplish this a little more simply than a full on script (like the previous PHP example).
In your controller:
def index
respond_to do |format|
format.html # Your HTML view
format.pdf { render :layout => false }
end
end
The render :layout => false part tells the browser to open up the "Would you like to download this file?" prompt instead of attempting to render the PDF. Then you would be able to link to the file normally: http://mysite.com/myawesomepdf.pdf
This is a common issue but few people know there's a simple HTML 5 solution:
<a href="./directory/yourfile.pdf" download="newfilename">Download the pdf</a>
Where newfilename
is the suggested filename for the user to save the file. Or it will default to the filename on the serverside if you leave it empty, like this:
<a href="./directory/yourfile.pdf" download>Download the pdf</a>
Compatibility: I tested this on Firefox 21 and Iron, both worked fine. It might not work on HTML5-incompatible or outdated browsers. The only browser I tested that didn't force download is IE...
Check compatibility here: http://caniuse.com/#feat=download
I found a way to do it with plain old HTML and JavaScript/jQuery that degrades gracefully. Tested in IE7-10, Safari, Chrome, and FF:
HTML for download link:
<p>Thanks for downloading! If your download doesn't start shortly,
<a id="downloadLink" href="...yourpdf.pdf" target="_blank"
type="application/octet-stream" download="yourpdf.pdf">click here</a>.</p>
jQuery (pure JavaScript code would be more verbose) that simulates clicking on link after a small delay:
var delay = 3000;
window.setTimeout(function(){$('#downloadLink')[0].click();},delay);
To make this more robust you could add HTML5 feature detection and if it's not there then use window.open()
to open a new window with the file.
In a Ruby on Rails application (especially with something like the Prawn gem and the Prawnto Rails plugin), you can accomplish this a little more simply than a full on script (like the previous PHP example).
In your controller:
def index
respond_to do |format|
format.html # Your HTML view
format.pdf { render :layout => false }
end
end
The render :layout => false part tells the browser to open up the "Would you like to download this file?" prompt instead of attempting to render the PDF. Then you would be able to link to the file normally: http://mysite.com/myawesomepdf.pdf
I know I am very late to answer this but I found a hack to do this in javascript.
function downloadFile(src){
var link=document.createElement('a');
document.body.appendChild(link);
link.href= src;
link.download = '';
link.click();
}
I solved mine using the whole url of the PDF file (Instead of just putting the file name or location to href): a href="domain . com/pdf/filename.pdf"
I know I am very late to answer this but I found a hack to do this in javascript.
function downloadFile(src){
var link=document.createElement('a');
document.body.appendChild(link);
link.href= src;
link.download = '';
link.click();
}
Instead of using a PHP script, to read and flush the file, it's more neat to rewrite the header using .htaccess
. This will keep a "nice" URL (myfile.pdf
instead of download.php?myfile
).
<FilesMatch "\.pdf$">
ForceType applicaton/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
This is a common issue but few people know there's a simple HTML 5 solution:
<a href="./directory/yourfile.pdf" download="newfilename">Download the pdf</a>
Where newfilename
is the suggested filename for the user to save the file. Or it will default to the filename on the serverside if you leave it empty, like this:
<a href="./directory/yourfile.pdf" download>Download the pdf</a>
Compatibility: I tested this on Firefox 21 and Iron, both worked fine. It might not work on HTML5-incompatible or outdated browsers. The only browser I tested that didn't force download is IE...
Check compatibility here: http://caniuse.com/#feat=download
This is the key:
header("Content-Type: application/octet-stream");
Content-type application/x-pdf-document or application/pdf is sent while sending PDF file. Adobe Reader usually sets the handler for this MIME type so browser will pass the document to Adobe Reader when any of PDF MIME types is received.
if you need to limit download rate, use this code !!
<?php
$local_file = 'file.zip';
$download_file = 'name.zip';
// set the download rate limit (=> 20,5 kb/s)
$download_rate = 20.5;
if(file_exists($local_file) && is_file($local_file))
{
header('Cache-control: private');
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($local_file));
header('Content-Disposition: filename='.$download_file);
flush();
$file = fopen($local_file, "r");
while(!feof($file))
{
// send the current file part to the browser
print fread($file, round($download_rate * 1024));
// flush the content to the browser
flush();
// sleep one second
sleep(1);
}
fclose($file);}
else {
die('Error: The file '.$local_file.' does not exist!');
}
?>
For more information click here
In a Ruby on Rails application (especially with something like the Prawn gem and the Prawnto Rails plugin), you can accomplish this a little more simply than a full on script (like the previous PHP example).
In your controller:
def index
respond_to do |format|
format.html # Your HTML view
format.pdf { render :layout => false }
end
end
The render :layout => false part tells the browser to open up the "Would you like to download this file?" prompt instead of attempting to render the PDF. Then you would be able to link to the file normally: http://mysite.com/myawesomepdf.pdf
Here's a different approach. I prefer rather than to rely on browser support, or address this at the application layer, to use web server logic.
If you are using Apache, and can put an .htaccess file in the relevant directory you could use the code below. Of course, you could put this in httpd.conf as well, if you have access to that.
<FilesMatch "\.(?i:pdf)$">
Header set Content-Disposition attachment
</FilesMatch>
The FilesMatch directive is just a regex so it could be set as granularly as you want, or you could add in other extensions.
The Header line does the same thing as the first line in the PHP scripts above. If you need to set the Content-Type lines as well, you could do so in the same manner, but I haven't found that necessary.
Try this:
<a href="pdf_server_with_path.php?file=pdffilename&path=http://myurl.com/mypath/">Download my eBook</a>
The code inside pdf_server_with_path.php is:
header("Content-Type: application/octet-stream");
$file = $_GET["file"] .".pdf";
$path = $_GET["path"];
$fullfile = $path.$file;
header("Content-Disposition: attachment; filename=" . Urlencode($file));
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . Filesize($fullfile));
flush(); // this doesn't really matter.
$fp = fopen($fullfile, "r");
while (!feof($fp))
{
echo fread($fp, 65536);
flush(); // this is essential for large downloads
}
fclose($fp);
Here's a different approach. I prefer rather than to rely on browser support, or address this at the application layer, to use web server logic.
If you are using Apache, and can put an .htaccess file in the relevant directory you could use the code below. Of course, you could put this in httpd.conf as well, if you have access to that.
<FilesMatch "\.(?i:pdf)$">
Header set Content-Disposition attachment
</FilesMatch>
The FilesMatch directive is just a regex so it could be set as granularly as you want, or you could add in other extensions.
The Header line does the same thing as the first line in the PHP scripts above. If you need to set the Content-Type lines as well, you could do so in the same manner, but I haven't found that necessary.
This is the key:
header("Content-Type: application/octet-stream");
Content-type application/x-pdf-document or application/pdf is sent while sending PDF file. Adobe Reader usually sets the handler for this MIME type so browser will pass the document to Adobe Reader when any of PDF MIME types is received.
Instead of using a PHP script, to read and flush the file, it's more neat to rewrite the header using .htaccess
. This will keep a "nice" URL (myfile.pdf
instead of download.php?myfile
).
<FilesMatch "\.pdf$">
ForceType applicaton/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
Source: Stackoverflow.com