如何强制文件在浏览器中打开而不是下载(PDF)?


209

当未选中“在浏览器中显示PDF”选项时,是否有一种方法可以强制在浏览器中打开PDF文件?

我尝试使用embed标签和iframe,但只有在选中该选项后才能使用。

我能做什么?

Answers:


418

为了向浏览器指示应在浏览器中查看文件,HTTP 响应应包括以下标头:

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

下载而不是查看文件:

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

如果文件名包含特殊字符(例如filename[1].pdf,否则可能会破坏浏览器处理响应的能力),则必须在文件名周围加上引号。

设置HTTP响应标头的方式将取决于HTTP服务器(或者,如果您是从服务器端代码生成PDF响应的:服务器端编程语言)。


13
要强制下载,我宁愿使用Content-Type:application / octet-stream。
Papick G. Taboada

25
@ PapickG.Taboada,但是用户的系统可能不知道文件类型。例如,某些用户可能选择了“始终打开此类型的文件”以获取PDF文件。也许,如果您想覆盖用户的首选项,那么八位字节流将是可行的方法,但是提供正确的类型和建议的文件名是提供下载的“正确”方法。
ColinM

2
嗨@ColinM我在这里有点困惑...我们在渲染pdf时遇到了问题,它只是提供了乱码。我们在哪里设置Content-Type:application / pdf Content-Disposition:内联;“ filename.pdf”?'cos,我们使用angular-js代码上传。所以我的问题是上传之前应该设置内容类型吗?而且,我们仅从后端团队获得一个链接,即提供文件路径的url,该链接使用以下方法在新选项卡中打开:window.open(url,'_blank')。focus();
Kailas 2014年

3
@Kailas我不明白您要做什么。答案是指服务器在响应PDF文件的HTTP请求时应发送给客户端的标头。这些头文件对文件上传没有影响,您需要在每次客户端下载文件时都在url后面的代码设置头文件。
ColinM 2014年

1
@ColinM感谢朋友,您说的没错,我们调试的问题是在上传文件时设置了mime类型。这应该由后端团队完成。我试图获取有关如何在Java脚本中添加标头的代码,但未成功。谢谢,当我把真正的想法从您的
脑中

19

如果您使用的是HTML5(现在我猜每个人都在使用),则有一个名为的属性download

例如,

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

filename是可选的,但是如果提供的话,它将使用下载文件的名称。


2
如果您可以控制服务器代码,则应使用“附件”,因为这将允许使用相同的文件名生成代码。如果您无法控制服务器,那么这是一个很好的解决方案。
Christophe Roussy 2015年

这是解决该问题的绝妙方法,但是与往常一样,IE阻止我们使用它:caniuse.com/#search=download
罗里·麦克罗斯

1
需要注意的重要一点是,这不适用于跨域(例如,同源策略阻碍了该过程)。如果从一个域下载,则将内容存储在另一个域上时,download属性将不起作用。CORS可能允许该内容通过(未经测试)。
vol7ron

59
这实际上是与OP要求的相反:)
Chuck Le Butt

1
是的!:\我理解错误的问题并回答。但是很多人只在这里找到相反的地方,这就是为什么不编辑/删除答案的原因。
阿克沙伊(Akshay)

16

正确的类型适用application/pdf于PDF,而不适用application/force-download。对于某些旧版浏览器来说,这看起来像是黑客。如果可以,请始终使用正确的模仿类型。

如果您可以控制服务器代码:

  • 强制下载/提示:使用 header("Content-Disposition", "attachment; filename=myfilename.myextension");
  • 浏览器尝试将其打开:使用 header("Content-Disposition", "inline; filename=myfilename.myextension");

无法控制服务器代码:

注意:我更喜欢在服务器端设置文件名,因为您可能有更多信息,并且可以使用通用代码。


2

如果您有Apache,请将其添加到.htaccess文件中:

<FilesMatch "\.(?i:pdf)$">
    ForceType application/octet-stream
    Header set Content-Disposition attachment
</FilesMatch>

我们如何添加多个扩展名?我也想添加DOC和XLS扩展名。请建议我。提前致谢。
卡姆列什

这与要求的相反
昆汀,

1

糟糕,我之前的帖子中有输入错误。

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

如果您不希望浏览器提示用户,请在第三个字符串中使用“内联”而不是“附件”。内联效果很好。PDF会立即显示,而无需用户单击“打开”。我使用了“附件”,这将提示用户打开,保存。我试图更改浏览器设置螺母,但它不会阻止提示。


4
以前是什么帖子?
Peter Mortensen

0

这是针对ASP.NET MVC

在您的cshtml页面中:

<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>

在您的控制器中:

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");
    }

-1

尽管以下内容在Firefox上运行良好,但在chrome浏览器和移动浏览器上不起作用。

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

要修复Chrome和移动浏览器错误,请执行以下操作:

  • 将文件存储在项目的目录中
  • 使用Google PDF Viewer

Google PDF Viewer可以这样使用:

<iframe src="http://docs.google.com/gview?url=http://example.com/path/to/my/directory/pdffile.pdf&embedded=true" frameborder="0"></iframe>

-4

从rootfile打开downloads.php。

然后转到第186行并将其更改为以下内容:

        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."\";");
        }

7
更不用说他们使用PHP。如果他们的后端使用Python或.NET怎么办?
Maxime Rouiller

1
...谈论左场。他甚至没有说他在说什么框架。
Archonic

-4

您可以通过以下方式执行此操作:

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

如果PDF文件位于某个文件夹内,并且该文件夹没有直接访问该文件夹中的文件的权限,则您必须.htaccess通过以下方式使用文件设置来绕过某些文件访问限制:

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

但是现在请确定必要的文件。

我已经使用了这段代码,并且效果很好。


更不用说他们使用Apache。如果他们使用IIS怎么办?还是快递?
Maxime Rouiller 2015年


-7

这是强制文件在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>';

1
header开始输出请求正文后,它不起作用(并且它不返回用于在HTML文档中进行连接的字符串)
Quentin

-9

只需打开Adobe Reader,菜单→ 编辑首选项Internet,然后更改为浏览器模式或有关不同浏览器的详细说明,请尝试在浏览器中显示PDF | Acrobat,Acrobat Reader


3
如果您不使用AdobeReader或不使用Windows怎么办?您的回答将行不通。而且,它要求用户更改设置,而这在现实世界中是做不到的。
Clawfire '16

-12

如果您链接到.PDF,它将在浏览器中打开。
如果未选中该框,则应链接到.zip以强制下载。

如果不能选择.zip,则使用PHP中的标头强制下载

header('Content-Type: application/force-download'); 
header('Content-Description: File Transfer'); 

是的,但是我需要一种强制在浏览器中打开而不下载的方法。我不知道是否可能。
elloalisboa 2011年

2
如果您不强迫它下载,那么就强迫它在浏览器中打开。如果无法在浏览器中打开它,那是因为用户具有特定的设置,您无法覆盖该设置,或者他们没有PDF阅读软件。
2011年

1
其实,看看我的答案。
加布里埃尔·赖安·纳米亚斯

21
错了 没有应用程序/强制下载。您也可以使用alskjdsdjk / aljksdlasdj。浏览器将下载,因为它不知道该MIME类型。正确的MIME类型下载将是我的应用程序/八位位组流
Papick G. Taboada 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.