Я пытаюсь запустить принудительную загрузку zip-файла, содержащего большое количество изображений. Я использую php для принудительной загрузки, и он работает на nginx. Странно то, что когда я использую wget для загрузки файла, он обычно работает, но когда я пытаюсь загрузить его с помощью браузера, размер файла оказывается меньше нескольких тысяч байтов. Я пробовал файлы разных размеров с похожими результатами. Я не думаю, что это ошибка тайм-аута, потому что я играл с замедлением скорости загрузки, и она всегда останавливается в одном и том же месте (в этом конкретном файле). Понятия не имею, почему это будет работать на wget, но не на браузере. Я пробовал его на нескольких компьютерах (с разными браузерами) и в нескольких сетях и получил те же результаты. Я поигрался с PHP-кодом, который обслуживает файл, и с настройками php.ini и nginx безрезультатно. Я был бы очень признателен за любую помощь или предложения, которые могут быть у кого-либо, это действительно поможет мне!
Вот мой PHP-код, который вызывает загрузку:
ob_end_flush();
header('Content-Description: File Transfer');
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="'.$name.'.zip"');
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($archive));
flush();
readfile($archive);
где $ archive - это путь к zip-файлу, который пользователь пытается загрузить.
Может ли ваш веб-сервер применять gzip Content-Encoding к файлу, который вы выводите из PHP (или вы могли включить его в самом PHP, например zlib.output_compression
)? При архивировании уже заархивированного файла фактический файл становится больше, поэтому, если клиент прочитает заголовок Content-Length скрипта, он прекратит загрузку до того, как будет выведен заархивированный файл большего размера.
wget
не поддерживает сжатие, поэтому сервер не будет пытаться использовать Content-Encoding при подключении с помощью wget. Попробуй с curl
и посмотрите, есть ли у вас битый файл. Если вы используете Chrome, Ctrl-сдвиг-J , чтобы открыть Инструменты разработчика и перейти на вкладку Сеть. Пока оно открыто, вернитесь в главное окно, из которого вы его открыли, и нажмите ссылку, чтобы загрузить файл. Он должен создать запись в списке запросов, на который вы можете щелкнуть, что откроет подокно с вкладкой «Заголовки», где вы можете увидеть, есть ли у него Content-Encoding:
линия в Response Headers:
раздел.
Кстати, я думаю, ты хочешь сделать ob_end_clean()
там, а не ob_end_flush()
поскольку _flush()
отправляет клиенту все, что есть в буфере, а _clean()
удаляет буфер и все уже находящиеся в нем заголовки.