php 将文件作为附件发送到浏览器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5641492/
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 22:03:16  来源:igfitidea点击:

Sending file to a browser as attachment

phphttpredirectheader

提问by 12 secs ago

How to send a file to the browser as attachment if the meant file resides on a 3rd party server (without prior downloading or streaming)?

如果所指的文件驻留在第 3 方服务器上(无需事先下载或流式传输),如何将文件作为附件发送到浏览器?

回答by RobertPitt

From another server without downloading to your server:

从另一台服务器无需下载到您的服务器:

header('Location: http://thirdparty.com/file.ext');

Without downloading the file locally you have no authorization in the external server, so you have to tell the browser what to do, thus the redirect header, it will tell the server to go directly to the url provided, thus loading the download.

没有在本地下载文件,你在外部服务器中没有授权,所以你必须告诉浏览器做什么,因此重定向头,它会告诉服务器直接转到提供的 url,从而加载下载。

From your server you would do:

从您的服务器,您将执行以下操作:

if (file_exists($file))
{
    if(false !== ($handler = fopen($file, 'r')))
    {
        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)); //Remove

        //Send the content in chunks
        while(false !== ($chunk = fread($handler,4096)))
        {
            echo $chunk;
        }
    }
    exit;
}
echo "<h1>Content error</h1><p>The file does not exist!</p>";

Taken from another questionI have answered

摘自我回答过的另一个问题

回答by drudge

http://php.net/manual/en/function.header.php#example-3655

http://php.net/manual/en/function.header.php#example-3655

If you want the user to be prompted to save the data you are sending, such as a generated PDF file, you can use the ? Content-Disposition header to supply a recommended filename and force the browser to display the save dialog.

如果您希望提示用户保存您发送的数据,例如生成的 PDF 文件,您可以使用 ? Content-Disposition 标头提供推荐的文件名并强制浏览器显示保存对话框。

<?php
// We'll be outputting a PDF
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');
?>

回答by Marc B

As the others have said, you have to set the Content-disposition header of the response to the file download request. However, you've said the file's on a 3rd party server. Unless you have control over how that server sends out the file, you can't change how the browser retrieves from that server.

正如其他人所说,您必须设置响应文件下载请求的 Content-disposition 标头。但是,您已经说过该文件位于第 3 方服务器上。除非您可以控制该服务器发送文件的方式,否则您无法更改浏览器从该服务器检索的方式。

You can, however, proxy the file so that your server downloads the file, then passes it on to the client with the appropriate headers. This means you've doubled your bandwidth bill, though, as you're having to both download the file AND upload it at the same time.

但是,您可以代理该文件,以便您的服务器下载该文件,然后将其传递给具有适当标头的客户端。但是,这意味着您的带宽费用翻了一番,因为您必须同时下载文件和上传文件。

回答by Borza Adrian

Just a note for those who face problems on names containing spaces (e.g. "test test.pdf").

对于那些在包含空格的名称(例如“test test.pdf”)上遇到问题的人来说,这只是一个注释。

In the examples (99% of the time) you can find header('Content-Disposition: attachment; filename='.basename($file));

在示例中(99% 的时间),您可以找到 header('Content-Disposition: attachment; filename='.basename($file));

but the correct way to set the filename is quoting it (double quote): header('Content-Disposition: attachment; filename="'.basename($file).'"' );

但设置文件名的正确方法是引用它(双引号): header('Content-Disposition: attachment; filename="'.basename($file).'"' );

Some browsers may work without quotation, but for sure not Firefox and as Mozilla explains, the quotation of the filename in the content-disposition is according to the RFC http://kb.mozillazine.org/Filenames_with_spaces_are_truncated_upon_download

某些浏览器可能无需引用即可工作,但肯定不是 Firefox,正如 Mozilla 解释的那样,内容处置中的文件名引用是根据 RFC http://kb.mozillazine.org/Filenames_with_spaces_are_truncated_upon_download

回答by Jonas

If you want to provide files that are regularly handled by the browser (images, html, ...), you will have add a header to change the MIME type with something like:

如果您想提供由浏览器定期处理的文件(图像、html 等),您需要添加一个标题来更改 MIME 类型,例如:

header("Content-Type: application/force-download; name=filename");

header("Content-Type: application/force-download; name=filename");

If you don't have access to the third party server, you have no choice but to download the file yourself to provide it to the user by adding the header

如果您无权访问第三方服务器,则您别无选择,只能自己下载文件,通过添加标头将其提供给用户