Использование заголовка в качестве ссылки для скачивания в PHP - PullRequest
4 голосов
/ 13 августа 2010

Итак, у меня проблема с моей ссылкой для скачивания.По сути, мой предыдущий способ создания ссылки на скачивание - просто иметь кнопку формы с method = 'link' и действие, которое будет ссылкой на файл.Это работает для Firefox и других, но не для сафари.По какой-то причине, когда пользователь пытается загрузить файл (файл Excel) из safari, он просто отображает кучу символов 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 (), но, похоже, она не работает для меня.Я делаю это на локальном хосте.

Ответы [ 2 ]

5 голосов
/ 13 августа 2010

Что-то вроде этого работает отлично.

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));
3 голосов
/ 13 августа 2010

Если я правильно вас понимаю, скрипт работает должным образом, то есть, если браузер распознает тип MIME:

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

Затем он ПОКАЗЫВАЕТ его в браузере (правильно ли он отображает что-то другое)1004 *

Поскольку вы хотите принудительно загружать показ INSTEAD OF в браузере, используйте mime-тип:

'application/octet-stream'

Это должно работать во всех браузерах и принудительно загружать вместо отображения в браузере.

...