如何创建不需要右键单击的PDF下载链接?

时间:2009-12-10 01:58:43

标签: php javascript html web download

我正在访问一个网站,访问者应该可以下载pdf文件。 (有三个链接可供选择,但这是无关紧要的) 我想知道如何制作它,以便访问者只需点击链接而不必

right click > Save (target) As...

我对PHP和/或Javascript解决方案持开放态度。感谢。

编辑:我可以使用javascript调用PHP并通过AJAX保存文件吗?

EDIT2:我最后使用了Nirmal的解决方案,因为对于所有三个文件来说,它是最简单的。我不需要为三个PDF制作3个文件,我也不需要手动编码开关。 BalusC得到了检查,因为他/她的代码是第一个起来并且也做了伎俩。

6 个答案:

答案 0 :(得分:13)

您基本上需要做的就是将Content-Disposition标题设置为attachment以获得“另存为”对话框。这是启动PHP示例:

<?php
    header('Content-Type: application/pdf');
    header('Content-Disposition: attachment;filename="foo.pdf"');
    readfile('/path/to/foo.pdf');
?>

你不能也不想用Javascript做这件事。

重要提示:由于功能较差,在MSIE中,“另存为”对话框中的默认文件名不会从content-disposition标题中派生出来,而是请求中pathinfo的最后一部分URL。要解决此问题,请将PDF文件名附加到链接,例如http://example.com/pdf/foo.pdf。您甚至可以在PHP中使用它来读取pathinfo指定的PDF文件。以下是pdf.php的基本示例:

<?php
    $file_name = $_SERVER['PATH_INFO'];
    $file = '/path/to/pdf/files' . $file_name;
    if (file_exists($file)) {
        header('Content-Type: application/pdf');
        header('Content-Disposition: attachment;filename="' . basename($file_name) . '"');
        header('Content-Length: ' . filesize($file));
        readfile($file);
    } else {
        header('HTTP/1.1 404 Not Found');
    }
?>

但是,假设您MultiViews已开启,/pdf/将通过此PHP文件,或至少RewriteRule/pdf//pdf.php/ }。

这种方法的主要优点是,无论何时想要添加新的PDF文件或更改PDF文件名,都无需更改代码。

您甚至可以通过自动确定和设置正确的内容类型使其更通用:

<?php
    $file_name = $_SERVER['PATH_INFO'];
    $file = '/path/to/all/files' . $file_name;
    if (file_exists($file)) {
        header('Content-Type: ' . mime_content_type($file_name));
        header('Content-Disposition: attachment;filename="' . basename($file_name) . '"');
        header('Content-Length: ' . filesize($file));
        readfile($file);
    } else {
        header('HTTP/1.1 404 Not Found');
    }
?>

将其命名为files.php左右,然后您就可以使用通用的PHP下载程序,例如http://example.com/files/foo.pdfhttp://example.com/files/bar.zip等等。

希望这有帮助。

答案 1 :(得分:3)

如果您使用的是Apache,则可以使用包含PDF的文件夹中的.htaccess文件来执行此操作,而不必编写PHP包装脚本:

<Files *.pdf>
  Header set Content-Disposition attachment
</Files>

显然某些版本的IE / Adob​​e Reader不尊重Content-Disposition标题。您可以使用ForceType application/octet-stream

解决这些问题
<Files *.pdf>
  ForceType application/octet-stream
  Header set Content-Disposition attachment
</Files>

答案 2 :(得分:2)

如果您不想弄乱服务器端代码,如果这对您来说是一个低优先级的事情,您可以使用HTML5 download属性。

示例:

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

但是并非所有浏览器都支持此功能。根据{{​​3}},支持以下浏览器:

Chrome(14 +),Firefox(20 +),Opera(15 +)。

您还可以通过给出下载attr的值来指定文件名:

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

答案 3 :(得分:1)

首先发送Content-type: application/octet-stream标题时尝试使用PHP来提供文件。

答案 4 :(得分:1)

您可以添加HTTP标头来执行此操作,PHP Docs中有一个示例(参见示例一)

答案 5 :(得分:1)

以下代码可以为您提供帮助:

<?php
if(isset($_GET['docid'])){
    switch($_GET['docid']){
        case '1':
            $file = 'complete/path/to/pdf/file1';
            break;
        case '2':
            $file = 'complete/path/to/pdf/file2';
            break;
        case '3':
            $file = 'complete/path/to/pdf/file3';
            break;
        default:
            exit;
    }

    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, post-check=0, pre-check=0');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file));
        ob_clean();
        flush();
        readfile($file);
        exit;
    }
}

将此代码保存为php文件(例如,download.php)并从链接中调用它。该脚本的作用是读取pdf文件并将其输出到缓冲区。标题将强制处置为下载。

要调用第一个pdf,href为'/path/to/download.php?docid=1'
要调用第二个pdf,href为'/path/to/download.php?docid=2' 要调用第三个pdf,href为'/path/to/download.php?docid=3'

因此,您不需要AJAX来完成工作。