在PHP中使用Header作为下载链接

时间:2010-08-13 17:49:50

标签: php header http-headers

所以我的下载链接出现了这个问题。基本上我之前创建下载链接的方法是只有一个带有method ='link'的表单按钮,并且该操作是该文件的链接。这适用于Firefox和其他人,但不适用于safari。出于某种原因,当用户尝试从safari下载文件(excel文件)时,它只会在浏览器上显示一堆ascii字符(我猜它试图用浏览器读取它?)。好吧,我正在寻找另一个解决方案,似乎使用标头是这样做的方式。所以现在我尝试使用method ='post'和action ='download.php'创建一个表单按钮,其中有一个隐藏字段,其中包含指向该文件的链接。看起来像这样

function showDownloadWithHeader($link){
    echo "<form action='download.php' method='post' >";
    echo "<input class='downloadButton' type='submit' value='Download Report'>";
    echo "<input type='hidden' name='filename' value='$link'>";
    echo "</form>";
}

在download.php中,我只想让用户下载文件。

<?php
    if($_POST['filename'] == '' || empty($_POST['filename'])){
        exit;
    }

    $filename = $_POST['filename']; //the file is 2 folder down. e.g. data/stack/bla.xlsx
    $file = $filename;
    $extension = end(explode('.', $filename));
    error_reporting(E_ALL);
    ini_set("display_errors",1);
//  echo $filename;
//  echo "<br/>";
//  echo $extension;
//  echo filesize($filename);
//  echo "<br/>";
    switch($extension){
        case 'xls':
            $mimeType = 'application/vnd.ms-excel';
            break;
        case 'xlsx':
            $mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
            break;
    }
//  echo $mimeType;
    header('Content-Description: File Transfer');
    header('Content-Type: ' . $mimeType);
    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($filename);
    exit;
?>

我在php.net下的readfile()函数中看到了这个解决方案,但它似乎并不适合我。我在localhost上这样做。

2 个答案:

答案 0 :(得分:5)

这样的事情很好。

header("Pragma: public", true);
header("Expires: 0"); // set expiration time
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment; filename=".basename($file));
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($file));
die(file_get_contents($file));

答案 1 :(得分:3)

如果我理解正确,脚本按预期工作,即如果浏览器识别mime类型:

'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'

然后它在浏览器中显示它(无论它是否正确显示是其他东西)

由于你想强制它下载INSTEAD OF在浏览器中显示使用mime类型:

'application/octet-stream'

这应该适用于所有浏览器并强制下载而不是在浏览器中显示。