pdf 文件下载的正确 PHP 标头

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20080341/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 02:51:39  来源:igfitidea点击:

correct PHP headers for pdf file download

phppdfheader

提问by useyourillusiontoo

I'm really struggling to get my application to open a pdf when the user clicks on a link.

当用户单击链接时,我真的很难让我的应用程序打开 pdf。

So far the anchor tag redirects to a page which sends headers that are:

到目前为止,锚标记重定向到发送标头的页面:

$filename='./pdf/jobs/pdffile.pdf;

$url_download = BASE_URL . RELATIVE_PATH . $filename;


header("Content-type:application/pdf");



header("Content-Disposition:inline;filename='$filename");

readfile("downloaded.pdf");

this doesn't seem to work, has anybody successfully sorted this problem in the past?

这似乎不起作用,过去有人成功解决过这个问题吗?

回答by gat

Example 2 on w3schoolsshows what you are trying to achieve.

w3schools上的示例 2显示了您要实现的目标。

<?php
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");
?>
<?php
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");
?>

Also remember that,

还要记住,

It is important to notice that header() must be called before any actual output is sent (In PHP 4 and later, you can use output buffering to solve this problem)

需要注意的是 header() 必须在发送任何实际输出之前调用(在 PHP 4 及更高版本中,您可以使用输出缓冲来解决这个问题)

回答by Marin Vartan

$name = 'file.pdf';
//file_get_contents is standard function
$content = file_get_contents($name);
header('Content-Type: application/pdf');
header('Content-Length: '.strlen( $content ));
header('Content-disposition: inline; filename="' . $name . '"');
header('Cache-Control: public, must-revalidate, max-age=0');
header('Pragma: public');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
echo $content;

回答by Havenard

There are some things to be considered in your code.

在您的代码中需要考虑一些事项。

First, write those headers correctly. You will never see any server sending Content-type:application/pdf, the header is Content-Type: application/pdf, spaced, with capitalized first letters etc.

首先,正确编写这些标题。你永远不会看到任何服务器发送Content-type:application/pdf,标题是Content-Type: application/pdf,间隔,首字母大写等。

The file name in Content-Dispositionis the file name only, not the full path to it, and altrough I don't know if its mandatory or not, this name comes wrapped in "not '. Also, your last 'is missing.

Content-Disposition的文件名只是文件名,而不是它的完整路径,虽然我不知道它是否是强制性的,但这个名称包含在"not 中'。另外,你的最后一个'不见了。

Content-Disposition: inlineimplies the file should be displayed, not downloaded. Use attachmentinstead.

Content-Disposition: inline意味着应该显示文件,而不是下载文件。使用attachment来代替。

In addition, make the file extension in upper case to make it compatible with some mobile devices. (Update: Pretty sure only Blackberries had this problem, but the world moved on from those so this may be no longer a concern)

此外,将文件扩展名设为大写以使其与某些移动设备兼容。(更新:很确定只有黑莓有这个问题,但世界已经从这些问题转移了,所以这可能不再是一个问题)

All that being said, your code should look more like this:

话虽如此,您的代码应该更像这样:

<?php

    $filename = './pdf/jobs/pdffile.pdf';

    $fileinfo = pathinfo($filename);
    $sendname = $fileinfo['filename'] . '.' . strtoupper($fileinfo['extension']);

    header('Content-Type: application/pdf');
    header("Content-Disposition: attachment; filename=\"$sendname\"");
    header('Content-Length: ' . filesize($filename));
    readfile($filename);

Content-Lengthis optional but is also important if you want the user to be able to keep track of the download progress and detect if the download was interrupted. But when using it you have to make sure you won't be send anything along with the file data. Make sure there is absolutely nothing before <?phpor after ?>, not even an empty line.

Content-Length是可选的,但如果您希望用户能够跟踪下载进度并检测下载是否中断,这也很重要。但是在使用它时,您必须确保不会随文件数据一起发送任何内容。确保之前<?php或之后绝对没有任何内容?>,甚至没有空行。

回答by haayek

I had the same problem recently and this helped me:

我最近遇到了同样的问题,这对我有帮助:

    header('Content-Description: File Transfer'); 
    header('Content-Type: application/octet-stream'); 
    header('Content-Disposition: attachment; filename="FILENAME"'); 
    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("PATH/TO/FILE")); 
    ob_clean(); 
    flush(); 
    readfile(PATH/TO/FILE);      
    exit();

I found this answer here

我在这里找到了这个答案

回答by Krish R

Can you try this, readfileneed the full file path.

你可以试试这个吗,readfile需要完整的文件路径。

        $filename='/pdf/jobs/pdffile.pdf';            
        $url_download = BASE_URL . RELATIVE_PATH . $filename;            

        //header("Content-type:application/pdf");   
        header("Content-type: application/octet-stream");                       
        header("Content-Disposition:inline;filename='".basename($filename)."'");            
        header('Content-Length: ' . filesize($filename));
        header("Cache-control: private"); //use this to open files directly                     
        readfile($filename);

回答by Flash Thunder

You need to define the size of file...

您需要定义文件的大小...

header('Content-Length: ' . filesize($file));

And this line is wrong:

而这一行是错误的:

header("Content-Disposition:inline;filename='$filename");

header("Content-Disposition:inline;filename='$filename");

You messed up quotas.

你搞砸了配额。