Принудительная загрузка файла повреждена - PullRequest
1 голос
/ 30 марта 2012

У меня есть код загрузки файла на моем сайте, который работал отлично, пока я не сменил домен. Я проверил все ссылки и изменил все, и они работают FINE Однако по какой-то причине файл загружен поврежденным, и я не могу понять, почему.

Код:

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');
header('Pragma: public');
header('Content-Length: ' . filesize($file_url));
readfile($file_url);
exit;

$ FileName имеет имя + расширение. $ file_url Работает Отлично. если я повторяю URL и пытаюсь просмотреть его, я вижу файл.

Кто-нибудь может помочь?

EDIT: Я заметил, что браузер говорит: Ресурс интерпретируется как Документ, но передается с изображением MIME типа / png

1 Ответ

2 голосов
/ 30 марта 2012

Если загружаемые файлы являются изображениями (как упомянуто в комментариях), тогда заголовок Content-Type должен иметь соответствующий тип mime для этого изображения, например. "image / jpeg", "image / png" и т. д.

$size = getimagesize($file_url);
header("Content-type: {$size['mime']}");

«application / octet-stream» не должен использоваться в этом случае (часто использовался в прошлом для попытки принудительной загрузки, так как браузер не обязательно будет знать, что с ним делать). Заголовок «Content-Disposition: attachment» запускает загрузку.

Кроме того, вы упоминаете, что оригинальное имя файла на иврите ... Заголовок "filename =" должен указывать имя файла в US-ASCII для совместимости. UTF-8 возможен, но только с некоторым дополнительным «возня», и все же может быть несовместим с некоторыми браузерами.

EDIT # 1

Если вы используете буферизацию вывода, вам может потребоваться убедиться, что буфер вывода пуст и очищен перед попыткой загрузки файла, в противном случае все, что находится в буфере вывода, станет частью вашего скачанного файла и будет повреждено.

header('Content-Length: ' . filesize($file_url));
ob_clean();    // <<<<
flush();       // <<<<
readfile($file_url);

РЕДАКТИРОВАТЬ # 2 - Тип содержимого

По вашей ссылке на ответ на этот другой вопрос, который предлагает использовать application / octet-stream вместо image / jpg ... ответ в этом вопросе цитирует RFC 2616 , однако, это было заменено RFC 6266 , где это заявляет:

В соответствии с RFC 2616, применяется только тип диспозиции "приложение" к содержанию типа "application / octet-stream". Это ограничение имеет были удалены, потому что получатели на практике не проверяют содержимое тип, и это также препятствует правильному объявлению типа носителя.

Таким образом, правильнее указать правильный тип mime для изображения (как упомянуто выше). Хотя, в конце концов, важно то, что работает для вас, поскольку серверы / браузеры различаются и, к сожалению, не обязательно следуют стандартам.

Чтобы дополнительно поддержать аргумент для указания правильного mime-типа и не использовать «application / octet-stream», см. Следующий принятый ответ на вопрос о веб-мастерах ...

Что может помешать Chrome загружать файлы?

...