I was wondering how to make a PDF file link downloadable instead of opening them in the browser? How is this done in html? (I'd assume it's done via javascript or something).
-
3This is to my knowledge not scriptable behavior. Most browsers will have their own settings for the behavior of what to do with specific file types on download. – Bart Jul 22 '11 at 18:13
-
1As of HTML5, the OP should update the correct answer to Sarim's answer. – Omar Tariq Sep 18 '13 at 07:32
-
possible duplicate of [Force to open "Save As..." popup open at text link click for pdf in HTML](http://stackoverflow.com/questions/3802510/force-to-open-save-as-popup-open-at-text-link-click-for-pdf-in-html) – Ciro Santilli OurBigBook.com Nov 06 '14 at 22:33
-
This question has also been answered here: http://stackoverflow.com/a/30714824/847235 – intrepidis Jun 10 '15 at 16:31
16 Answers
With html5, it is possible now. Set a "download" attr in element.
<a href="http://link/to/file" download="FileName">Download it!</a>
Source : http://updates.html5rocks.com/2011/08/Downloading-resources-in-HTML5-a-download

- 3,124
- 2
- 20
- 20
-
You better go with this solution if it's supported. Here's a way to check if it is `if ("download" in document.createElement("a")){ ... }` – pmrotule Dec 13 '15 at 02:30
-
i added another answer below (bad hack though), while this is still the preferred way, perhaps the hack way could be offered for unsupported browsers. – Sarim Jan 11 '16 at 19:51
-
Is there a way one can specify the text for the pdf instead of mentioning file path? I need to create pdf from a div html but I don't wish to open another window,download should be seemless like in this answer.. – T.Adak Oct 24 '16 at 11:53
-
1As right now August 2019, Browser support seems to be enhanced for this feature, see: https://www.w3schools.com/tags/att_a_download.asp – Daniel Resch Aug 24 '19 at 21:51
-
19Note that the download attribute is only supported for same-origin requests. – Quentin May 04 '20 at 17:29
This is only possible with setting a http response header by the server side code. Namely;
Content-Disposition: attachment; filename=fname.ext

- 5,796
- 1
- 23
- 26
-
3this is the perfect answer - just find the way to do it in the appropriate server-side language. – user158017 Jul 25 '12 at 21:34
-
[Apache](https://serverfault.com/a/101966/161152) example. [Flask](https://stackoverflow.com/a/11017839/673991) example. – Bob Stein Apr 03 '18 at 13:57
-
Unfortunately iOS will still preview and not download pdf files even if the content disposition is 'attachment'. – Jorn van de Beek May 06 '19 at 14:47
-
There is now the HTML 5 download
attribute that can handle this.
I agree, and think Sarim's answer is good (it probably should be the chosen answer if the OP ever returns). However, this answer is still the reliable way to handle it (as Yiğit Yener's answer points out and--oddly--people agree with). While the download attribute has gained support, it's still spotty:
you will need to use a PHP script (or an other server side language for this)
<?php
// We'll be outputting a PDF
header('Content-type: application/pdf');
// It will be called downloaded.pdf
header('Content-Disposition: attachment; filename="downloaded.pdf"');
// The PDF source is in original.pdf
readfile('original.pdf');
?>
and use httacces to redirect (rewrite) to the PHP file instead of the pdf

- 4,533
- 1
- 16
- 29
-
Hmm, it works great when I open the php file directly. But when I try to use redirection, like here: Redirect 301 /_PDFs/Catalogue.pdf `http://www.example.com/_PDFs/___download_the_catalogue_instead_opening.php` and try to open the pdf file, it still opens the original in the browser, instead downloading the renamed version... – ellockie Jul 14 '15 at 09:58
-
UPDATE: It works when there is no file that is being directly called (as "Catalogue.pdf" in my example). Then the redirection works perfectly. Thanks! – ellockie Jul 14 '15 at 10:16
You can use
Response.AddHeader("Content-disposition", "attachment; filename=" + Name);
Check out this example:
http://www.codeproject.com/KB/aspnet/textfile.aspx
This goes for ASP.NET. I am sure you can find similar solutions in all other server side languages. However there's no javascript solution to the best of my knowledge.

- 8,904
- 12
- 38
- 54
-
this is the answer ( as well as the related one for PHP). the point is that the http response header has to be edited. – user158017 Jul 25 '12 at 21:34
When you want to direct download any image or pdf file from browser instead on opening it in new tab then in javascript you should set value to download attribute of create dynamic link
var path= "your file path will be here";
var save = document.createElement('a');
save.href = filePath;
save.download = "Your file name here";
save.target = '_blank';
var event = document.createEvent('Event');
event.initEvent('click', true, true);
save.dispatchEvent(event);
(window.URL || window.webkitURL).revokeObjectURL(save.href);
For new Chrome update some time event is not working. for that following code will be use
var path= "your file path will be here";
var save = document.createElement('a');
save.href = filePath;
save.download = "Your file name here";
save.target = '_blank';
document.body.appendChild(save);
save.click();
document.body.removeChild(save);
Appending child and removing child is useful for Firefox, Internet explorer browser only. On chrome it will work without appending and removing child

- 471
- 4
- 12
Without html5 attribute one can achieve this by using php:
Create php file named download.php with this code:
<?php
ob_start();
$file = "yourPDF.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();
}
Now if you want to automatically start downloading pdf write this javascript:
<script>window.location = "download.php";</script>
If you want this to work on a link, use this...
<a href='javascript:window.location = "download.php"'>
Download it!
</a>

- 1,489
- 18
- 31
-
4Just a heads up that you need to be careful when you are going to do this with URL parameters. For example `$file = $_GET['$file'];`. Because one could then also call `download.php?file=../../../wp-config.php` or any other given resource. Additional checking for extensions, mime-types and allowed paths to download from (and stripping stuff like "../") are very important! – Giel Berkers Apr 15 '15 at 12:04
-
is it me or doing is exactly the same as putting directly the link in ` ?` – allan.simon Aug 21 '18 at 07:41
I've had some issues with the suggested solution that creates an a
DOM element, and sets the download
attribute. It still displayed a popup warning in some browsers (perhaps they got a little stricter by 2021).
Adding the pdf mime type to the href
attribute solved the browser popup warning, but it messed up the file (the downloaded file got damaged and couldn't be opened).
In 2021 you can download a PDF file without browser warnings, without PHP or Apache settings, using an XMLHttpRequest
as suggested by Edhowler. His code example uses an npm library though. Here's how to do it using js only:
/**
* Download a file without browser popup warning
* @param {string} url The url of the file to download
* @param {string} filename Set a new filename for the downloaded file (optional)
*/
const downloadFile = (url, filename = '') => {
if (filename.length === 0) filename = url.split('/').pop();
const req = new XMLHttpRequest();
req.open('GET', url, true);
req.responseType = 'blob';
req.onload = function () {
const blob = new Blob([req.response], {
type: 'application/pdf',
});
const isIE = false || !!document.documentMode;
if (isIE) {
window.navigator.msSaveBlob(blob, filename);
} else {
const windowUrl = window.URL || window.webkitURL;
const href = windowUrl.createObjectURL(blob);
const a = document.createElement('a');
a.setAttribute('download', filename);
a.setAttribute('href', href);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
};
req.send();
};
downloadFile('https://domain.tld/file.pdf');
Use a transpiler like Babel if you need support for non ES6+ browsers.

- 1,619
- 13
- 16
-
-
Can you elaborate, Cristian? I assume that you're right, in case your file is not located on the same server. – jnaklaas Nov 30 '21 at 13:24
You can use download.js (https://github.com/rndme/download and http://danml.com/download.html). If the file is in an external URL, you must make an Ajax request, but if it is not, then you can use the function:
download(Path, name, mime)
Read their documentation for more details in the GitHub.

- 141
- 1
- 2
- 8
-
This is the best javascript solution for downloads in another domain. – Edhowler Jun 11 '20 at 17:04
-
-
The solution that worked best for me was the one written up by Nick on his blog
The basic idea of his solution is to use the Apache servers header mod and edit the .htaccess to include a FileMatch directive that the forces all *.pdf files to act as a stream instead of an attachment. While this doesn't actually involve editing HTML (as per the original question) it doesn't require any programming per se.
The first reason I preferred Nick's approach is because it allowed me to set it on a per folder basis so PDF's in one folder could still be opened in the browser while allowing others (the ones we would like users to edit and then re-upload) to be forced as downloads.
I would also like to add that there is an option with PDF's to post/submit fillable forms via an API to your servers, but that takes awhile to implement.
The second reason was because time is a consideration. Writing a PHP file handler to force the content disposition in the header() will also take less time than an API, but still longer than Nick's approach.
If you know how to turn on an Apache mod and edit the .htaccss you can get this in about 10 minutes. It requires Linux hosting (not Windows). This may not be appropriate approach for all uses as it requires high level server access to configure. As such, if you have said access it's probably because you already know how to do those two things. If not, check Nick's blog for more instructions.
As the html5 way (my previous answer) is not available in all browsers, heres another slightly hack way.
This solution requires you are serving the intended file from same domain, OR has CORS permission.
- First download the content of the file via XMLHttpRequest(Ajax).
- Then make a data URI by base64 encoding the content of the file and set media-type to
application/octet-stream
. Result should look like
data:application/octet-stream;base64,SGVsbG8sIFdvcmxkIQ%3D%3D
Now set location.href = data
. This will cause the browser to download the file. Unfortunately you can't set file name or extension this way. Fiddling with the media-type could yield something.
See details: https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs

- 3,124
- 2
- 20
- 20
I needed to do this for files created with dynamic names in a particular folder and served by IIS.
This worked for me:
- In IIS, go that folder and double click HTTP Response Headers.
Add a new header with the following info:
Name: content-disposition Value: attachment
(from: http://forums.iis.net/t/1175103.aspx?add+CustomHeaders+only+for+certain+file+types+)
If you are using HTML5 (and i guess now a days everyone uses that), there is an attribute called download
.
ex.
<a href="somepathto.pdf" download="filename">
here filename
is optional, but if provided, it will take this name for downloaded file.

- 3,558
- 4
- 43
- 77
-
Sadly, I have to admit that I am too stupid to understand this tag. I put this: `Download curriculum` or that: `Download curriculum` and I can see absolutely no difference in how it works. Both downloading my .zip. And in the second one using the filename option seems to do nothing at all. – Garavani Jun 02 '15 at 04:53
you can add the following code
<a href='http://v2.immo-facile.com/catalog/admin-v2/product_info.pdf' class='btnPdf' title='pdf' target='_blank' type='application/pdf' >Télécharger la fiche du bien</a>

- 1,011
- 9
- 17
@Aljohn Yamaro
function forceDownload(pdf_url, pdf_name) {
var x = new XMLHttpRequest();
x.open("GET", pdf_url, true);
x.responseType = 'blob';
x.onload = function(e){
saveAs(x.response, pdf_name, 'application/pdf');
};
x.send();
}

- 715
- 8
- 17
The behaviour should depend on how the browser is set up to handle various MIME types. In this case the MIME type is application/pdf. If you want to force the browser to download the file you can try forcing a different MIME type on the PDF files. I recommend against this as it should be the users choice what will happen when they open a PDF file.

- 8,266
- 29
- 36