How do I force files to open in the browser instead of downloading (PDF)?
Asked Answered
S

14

313

Is there a way to force PDF files to open in the browser when the option "Display PDF in browser" is unchecked?

I tried using the embed tag and an iframe, but it only works when that option is checked.

What can I do?

Socialite answered 9/6, 2011 at 13:54 Comment(1)
Are you asking how to achieve this server side? Or how to set a preference/override client side in your favorite web browser? If so which one?Pettitoes
M
572

To indicate to the browser that the file should be viewed in the browser, the HTTP response should include these headers:

Content-Type: application/pdf
Content-Disposition: inline; filename="filename.pdf"

To have the file downloaded rather than viewed:

Content-Type: application/pdf
Content-Disposition: attachment; filename="filename.pdf"

The quotes around the filename are required if the filename contains special characters such as filename[1].pdf which may otherwise break the browser's ability to handle the response.

How you set the HTTP response headers will depend on your HTTP server (or, if you are generating the PDF response from server-side code: your server-side programming language).

Merkle answered 10/8, 2012 at 2:45 Comment(7)
To force download I rather use Content-Type: application/octet-stream.Beisel
@PapickG.Taboada but then the user's system may not know the file type. E.g. some user's may have opted to "Always open files of this type" for PDF files. Perhaps if you want to override the user's preferences then octet-stream would be the way to go, but giving the correct type and a suggested filename is the "correct" way to provide a download.Merkle
hi @Merkle I am a bit confused here... we are having issues rendering the pdf, it just gives a scrambled text. where do we set the Content-Type: application/pdf Content-Disposition: inline; "filename.pdf"? 'cos, we upload it using angular-js code. So my question is should the content type be set before uploading? And also, we get only a link from the backend team, a url that gives the file path, that we open in new tab using:window.open(url, '_blank').focus();Drowsy
@Drowsy I don't understand what you're trying to do.. The answer is referring to the headers that a server should send to a client when responding to an HTTP request for the PDF file. These headers have no effect on a file upload, you need to have the code behind the url set the headers every time it is downloaded by the client.Merkle
@Merkle Thanks buddy, you said it right, the issue when we debugged was the mime type was set while uploading the files. This should be done by the back-end team. I tried to get codes on how to add headers in java script but was not successful. Thanks, as I got the real idea cleared from you... :)Drowsy
Not working for me. I set Content-Type and Content-Disposition from the server. Opened file using URL, the browser is still asking to download and not opening in the browser.Pusey
Worked for me - for those using PDF's in S3 with a presigned URL i needed to set the meta data of the object IN S3 to be application/pdf. Then it was a simple as using an embed tag with the URL <embed src="{presigned_s3_url}" />Halliard
A
23

The correct type is application/pdf for PDF, not application/force-download. This looks like a hack for some legacy browsers. Always use the correct mimetype if you can.

If you have control over the server code:

  • Forced download/prompt: use header("Content-Disposition", "attachment; filename=myfilename.myextension");
  • Browser tries to open it: use header("Content-Disposition", "inline; filename=myfilename.myextension");

No control over the server code:

NOTE: I prefer setting the filename on the server side as you may have more information and can use common code.

Afield answered 4/2, 2015 at 14:13 Comment(0)
R
22

(I misread the question, the following answer is about forcefully downloading the file instead of opening it in the browser)

If you are using HTML5 (and I guess nowadays everyone uses that), there is an attribute called download.

For example,

<a href="somepathto.pdf" download="filename">

Here filename is optional, but if provided, it will take this name for the downloaded file.

EDIT

I know this is the opposite of what the question asked. I am keeping the opposite answer for those (like me) who came searching for the opposite question (Evidence: this answer has more upvotes then downvotes)

Ritualize answered 1/10, 2014 at 10:0 Comment(7)
If you have control over the server code you should use 'attachement' as this will allow to use the same filename generation code. If you have no control over the server this is a good solution.Afield
This is a brilliant solution to the problem however, as always, IE is holding us back from using it: caniuse.com/#search=downloadMaryrose
Well, the 'edge' supports it, however 'safari' does not. Ref w3schools.com/tags/att_a_download.aspRitualize
Important to note that this does not work across domains (e.g., same-origin policy gets in the way). If downloading from one domain, the download attribute will not work if content is stored on a different domain. CORS may allow that content to pass through (haven't tested).Slapbang
This is literally the opposite of what the OP is asking :)Gauthier
Yes figured! :\ I understood the question wrong and answered. But many people lands here finding the opposite only, that's why not edited/removed the answer.Ritualize
It is literally the opposite of what the OP is asking... and yet the OP accepted an answer that does exactly that, too. Upvoted for finding something new.Celloidin
R
5

I had the same issue and most of the above answers should resolve your issue. Unfortunately, even if i was receiving the content-type & content-disposition headers in the response but still my pdf was being downloaded rather than viewed. After brainstorming and trying for many hours.

The Culprit was firefox, well in a way it was me. Nervous Laughter

By default, when you open a pdf file in firefox, it will provide you with a popup to either save the pdf file or to open it directly and there is also a check box which says do this action automatically from now on and guess who selected it.

Due to this mistake, my pdf was being downloaded rather than viewed, even if had all the required headers in response. This is a simple mistake but cost me a good amount of time.

To resolve this, just go to settings and search for applications and change pdf setting to whatever you need.

Radiothorium answered 7/6, 2021 at 5:15 Comment(1)
Yes to overwrite Firefox user preferences and make sure the PDF open, it seems the only solution is to use a third party script like PDF.js or the Google PDF Viewer mentioned in another post.Boer
C
1

This is for ASP.NET MVC

In your cshtml page:

<section>
    <h4><a href="@Url.Action("Download", "Document", new { id = @Model.GUID })"><i class="fa fa-download"></i> @Model.Name</a></h4>
    <object data="@Url.Action("View", "Document", new { id = @Model.GUID })" type="application/pdf" width="100%" height="800" class="col-md-12">
        <h2>Your browser does not support viewing PDFs, click on the link above to download the document.</h2>
    </object>
</section>

In your controller:

public ActionResult Download(Guid id)
    {
        if (id == Guid.Empty)
            return null;

        var model = GetModel(id);

        return File(model.FilePath, "application/pdf", model.FileName);
    }

public FileStreamResult View(Guid id)
    {
        if (id == Guid.Empty)
            return null;

        var model = GetModel(id);

        FileStream fs = new FileStream(model.FilePath, FileMode.Open, FileAccess.Read);

        return File(fs, "application/pdf");
    }
Calash answered 29/11, 2016 at 11:5 Comment(0)
M
1

While the following works well on firefox, it DOES NOT work on chrome and mobile browsers.

Content-Type: application/pdf
Content-Disposition: inline; filename="filename.pdf"

To fix the chrome & mobile browsers error, do the following:

  • Store your files on a directory in your project
  • Use the google PDF Viewer

Google PDF Viewer can be used as so:

<iframe src="http://docs.google.com/gview?url=http://example.com/path/to/my/directory/pdffile.pdf&embedded=true" frameborder="0"></iframe>
Monosyllabic answered 11/5, 2020 at 13:55 Comment(1)
I found your suggestion of the Google PDF viewer to be very useful. I needed to link to a PDF hosted on an external site. Linking directly resulted in a download, but using the Google link caused it to be displayed in the browser. No iframe is needed, though. Just linking to to the viewer is enough.Sublunar
E
0

If you have Apache add this to the .htaccess file:

<FilesMatch "\.(?i:pdf)$">
    ForceType application/octet-stream
    Header set Content-Disposition attachment
</FilesMatch>
Epigene answered 11/8, 2015 at 10:20 Comment(2)
how can we add multiple extensions? I want to add DOC and XLS extension also. Kindly suggest me. Thanks in advance.Abstention
That does the opposite to what is asked forPainting
E
-1

Oops, there were typing errors in my previous post.

    header("Content-Type: application/force-download");
    header("Content-type: application/pdf");
    header("Content-Disposition: inline; filename=\"".$name."\";");

If you don't want the browser to prompt the user then use "inline" for the third string instead of "attachment". Inline works very well. The PDF display immediately without asking the user to click on Open. I've used "attachment" and this will prompt the user for Open, Save. I've tried to change the browser setting nut it doesn't prevent the prompt.

Exarate answered 22/11, 2014 at 15:38 Comment(1)
What previous post?Warenne
G
-2

for large files you need to get your output buffer started add :-

ob_start(); // at the start

..//your code

ob_clean();// at the end of you file

Gilleod answered 6/5, 2022 at 11:59 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Hiroko
W
-6

You can do this in the following way:

<a href="path to PDF file">Open PDF</a>

If the PDF file is inside some folder and that folder doesn't have permission to access files in that folder directly then you have to bypass some file access restrictions using .htaccess file setting by this way:

<FilesMatch ".*\.(jpe?g|JPE?G|gif|GIF|png|PNG|swf|SWF|pdf|PDF)$" >
    Order Allow,Deny
    Allow from all
</FilesMatch>

But now allow just certain necessary files.

I have used this code and it worked perfectly.

Walford answered 9/11, 2012 at 10:33 Comment(1)
No mention that they use Apache. What if they use IIS? Or Express?Mechanistic
B
-7

Open downloads.php from rootfile.

Then go to line 186 and change it to the following:

        if(preg_match("/\.jpg|\.gif|\.png|\.jpeg/i", $name)){
            $mime = getimagesize($download_location);
            if(!empty($mime)) {
                header("Content-Type: {$mime['mime']}");
            }
        }
        elseif(preg_match("/\.pdf/i", $name)){
            header("Content-Type: application/force-download");
            header("Content-type: application/pdf");
            header("Content-Disposition: inline; filename=\"".$name."\";");
        }

        else{
            header("Content-Type: application/force-download");
            header("Content-type: application/octet-stream");
            header("Content-Disposition: attachment; filename=\"".$name."\";");
        }
Beller answered 12/11, 2014 at 14:29 Comment(2)
No mention that they use PHP. What if their backend is in Python or .NET?Mechanistic
... talk about out of left field. He doesn't even say what framework he's talking about.Rothman
S
-7

Here is another method of forcing a file to view in the browser in PHP:

$extension = pathinfo($file_name, PATHINFO_EXTENSION);
$url = 'uploads/'.$file_name;
        echo '<html>'
                .header('Content-Type: application/'.$extension).'<br>'
                .header('Content-Disposition: inline; filename="'.$file_name.'"').'<br>'
                .'<body>'
                .'<object   style="overflow: hidden; height: 100%;
             width: 100%; position: absolute;" height="100%" width="100%" data="'.$url.'" type="application/'.$extension.'">
                    <embed src="'.$url.'" type="application/'.$extension.'" />
             </object>'
            .'</body>'
            . '</html>';
Surveying answered 25/2, 2015 at 11:15 Comment(1)
header doesn't work after you're started outputting the request body (and it doesn't return a string for concatenating in an HTML document)Painting
T
-11

Either use

<embed src="file.pdf" />

if embedding is an option or my new plugin, PIFF: https://github.com/terrasoftlabs/piff

Terrance answered 25/4, 2012 at 5:6 Comment(0)
P
-17

If you link to a .PDF it will open in the browser.
If the box is unchecked it should link to a .zip to force the download.

If a .zip is not an option, then use headers in PHP to force the download

header('Content-Type: application/force-download'); 
header('Content-Description: File Transfer'); 
Pontormo answered 9/6, 2011 at 13:56 Comment(3)
Yes, but I need a way to force to open in browser not to download. I have no idea if its possible.Socialite
If you aren't forcing it to download, then you ARE forcing it to open in the browser. If it won't open in the browser, it's because the user has specific setting, which you can't override or they don't have PDF reading software.Pontormo
This is wrong. There is no application/force-download. You can use alskjdsdjk/aljksdlasdj as well. The browser will download because it does not know this mime-type. The right mime-type for download would me application/octet-streamBeisel

© 2022 - 2024 — McMap. All rights reserved.