开发者

Sending file to a browser as attachment

How to send a file to the browser as attachment if the meant fil开发者_Go百科e resides on a 3rd party server (without prior downloading or streaming)?


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.

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 question I have answered


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.

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


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.

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.


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

In the examples (99% of the time) you can find

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

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

Filename with spaces truncated upon download - Mozillazine


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:

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜