132

我在我的网页上提供了一个 pdf 文件的链接以供下载,如下所示

<a href="myfile.pdf">Download Brochure</a>

问题是当用户点击此链接时

  • 如果用户已安装 Adob​​e Acrobat,则它会在 Adob​​e Reader 的同一浏览器窗口中打开该文件。
  • 如果未安装 Adob​​e Acrobat,则会弹出用户下载文件。

但我希望它总是弹出给用户下载,无论是否安装了“Adobe acrobat”。

请告诉我我该怎么做?

4

14 回答 14

234

这是一个常见问题,但很少有人知道有一个简单的 HTML 5 解决方案:

<a href="./directory/yourfile.pdf" download="newfilename">Download the pdf</a>

newfilename建议用户保存文件的文件名在哪里。或者,如果您将其留空,它将默认为服务器端的文件名,如下所示:

<a href="./directory/yourfile.pdf" download>Download the pdf</a>

兼容性:我在 Firefox 21 和 Iron 上进行了测试,都运行良好。它可能不适用于不兼容 HTML5 或过时的浏览器。我测试的唯一没有强制下载的浏览器是 IE ......

在此处检查兼容性:http: //caniuse.com/#feat=download

于 2013-06-09T15:46:50.117 回答
118

而不是链接到 .PDF 文件,而是执行类似的操作

<a href="pdf_server.php?file=pdffilename">Download my eBook</a>

它输出自定义标题,打开 PDF(二进制安全)并将数据打印到用户的浏览器,然后他们可以选择保存 PDF,尽管他们的浏览器设置。pdf_server.php 应如下所示:

header("Content-Type: application/octet-stream");

$file = $_GET["file"] .".pdf";
header("Content-Disposition: attachment; filename=" . urlencode($file));   
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");            
header("Content-Length: " . filesize($file));
flush(); // this doesn't really matter.
$fp = fopen($file, "r");
while (!feof($fp))
{
    echo fread($fp, 65536);
    flush(); // this is essential for large downloads
} 
fclose($fp); 

PS:显然对“文件”变量运行一些健全性检查,以防止人们窃取您的文件,例如不接受文件扩展名,拒绝斜杠,将 .pdf 添加到值

于 2008-12-13T07:18:13.147 回答
50

不要遍历每个文件行。改用readfile,它更快。这是关闭 php 网站: 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;
}

确保清理您的 get 变量,因为有人可能会下载一些 php 文件...

于 2011-11-14T13:35:59.197 回答
24

与其使用 PHP 脚本来读取和刷新文件,不如使用.htaccess. 这将保留一个“不错”的 URL(myfile.pdf而不是download.php?myfile)。

<FilesMatch "\.pdf$">
ForceType applicaton/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
于 2012-02-09T10:24:00.613 回答
14

我找到了一种使用普通 HTML 和 JavaScript/jQuery 优雅降级的方法。在 IE7-10、Safari、Chrome 和 FF 中测试:

下载链接的HTML:

<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(纯 JavaScript 代码会更冗长)在一小段延迟后模拟点击链接:

var delay = 3000;
window.setTimeout(function(){$('#downloadLink')[0].click();},delay);

为了使它更健壮,您可以添加 HTML5 功能检测,如果不存在,则使用window.open()该文件打开一个新窗口。

于 2013-08-06T14:59:06.100 回答
7

这是关键:

header("Content-Type: application/octet-stream");

发送 PDF 文件时发送内容类型 application/x-pdf-document 或 application/pdf。Adobe Reader 通常会为此 MIME 类型设置处理程序,以便浏览器在收到任何 PDF MIME 类型时将文档传递给 Adob​​e Reader。

于 2008-12-13T07:27:19.617 回答
3

我知道我很晚才回答这个问题,但我发现了一个在 javascript 中执行此操作的技巧。

function downloadFile(src){
    var link=document.createElement('a');
    document.body.appendChild(link);
    link.href= src;
    link.download = '';
    link.click();
}
于 2017-02-24T18:48:24.440 回答
3

这可以使用 HTML 来实现。

<a href="myfile.pdf">Download Brochure</a>

为其添加下载属性:这里的文件名将是 myfile.pdf

<a href="myfile.pdf" download>Download Brochure</a>

为下载属性指定一个值:

<a href="myfile.pdf" download="Brochure">Download Brochure</a>

这里的文件名是 Brochure.pdf

于 2020-11-19T11:30:19.027 回答
0

试试这个:

<a href="pdf_server_with_path.php?file=pdffilename&path=http://myurl.com/mypath/">Download my eBook</a>

pdf_server_with_path.php 里面的代码是:

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);
于 2012-06-21T02:15:48.260 回答
0

这是一种不同的方法。我更喜欢而不是依赖浏览器支持,或者在应用程序层解决这个问题,来使用 Web 服务器逻辑。

如果您使用的是 Apache,并且可以将 .htaccess 文件放在相关目录中,则可以使用下面的代码。当然,如果您可以访问它,您也可以将它放在 httpd.conf 中。

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

FilesMatch 指令只是一个正则表达式,因此可以根据需要进行精细设置,也可以添加其他扩展。

Header 行与上述 PHP 脚本中的第一行执行相同的操作。如果您还需要设置 Content-Type 行,您可以以相同的方式进行,但我认为没有必要。

于 2016-11-29T16:52:53.317 回答
0

我使用 PDF 文件的整个 url 解决了我的问题(而不仅仅是将文件名或位置放在 href 中):a href="domain .com/pdf/filename.pdf"

于 2017-06-05T11:05:41.027 回答
0

如果您需要限制下载速率,请使用此代码!

<?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!');
}

?>

欲了解更多信息,请单击此处

于 2019-02-06T05:30:29.490 回答
0
<!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>   
于 2019-02-06T08:38:32.040 回答
-1

在 Ruby on Rails 应用程序中(尤其是使用 Prawn gem 和 Prawnto Rails 插件之类的东西),您可以比完整的脚本(如前面的 PHP 示例)更简单地完成此操作。

在您的控制器中:

def index

 respond_to do |format|
   format.html # Your HTML view
   format.pdf { render :layout => false }
 end
end

render :layout => false 部分告诉浏览器打开“你想下载这个文件吗?” 提示而不是尝试呈现 PDF。然后你就可以正常链接到文件了:http: //mysite.com/myawesomepdf.pdf

于 2008-12-13T07:49:25.253 回答