заголовки для принудительной загрузки архива tar - PullRequest
2 голосов
/ 04 августа 2010

У меня есть архив tar на сервере, который должен быть загружен через php.Это код, который я использовал:

$content=file_get_contents($tar);
header("Content-Type: application/force-download");
header("Content-Disposition: attachment; filename=$tar");
header("Content-Length: ".strlen($content));    
unlink($name);
die($content);

Файл загружен, но он поврежден и не может быть открыт.Я думаю, что с заголовками что-то не так, потому что файл на сервере можно открыть без проблем.Вы знаете, как я могу решить эту проблему?

ОБНОВЛЕНИЕ Я пытался напечатать iframe следующим образом:

<iframe src="<?php echo $tar?>"></iframe>

И загрузка работает, поэтомуя уверен, что в заголовках чего-то не хватает.

Ответы [ 5 ]

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

Не используйте file_get_contents(), а затем echo или print для вывода файла. Это загружает все содержимое файла в память. Большой файл может / превысит memory_limit вашего скрипта и уничтожит скрипт.

Для выгрузки содержимого файла на клиент лучше всего использовать readfile() - он будет правильно отбрасывать куски файлов и выплевывать их на клиенте, не превышая доступную память. Просто не забудьте отключить буферизацию вывода перед тем, как сделать это, иначе вы просто делаете file_get_contents() снова

Итак, в итоге вы получите:

$tar = 'somefile.tar';
$tar_path = '/the/full/path/to/where/the/file/is' . $tar;
$size = filesize($tar_path);

header("Content-Type: application/x-tar");
header("Content-Disposition: attachment; filename='".$tar."'");
header("Content-Length: $size");    
header("Content-Transfer-Encoding: binary");

readfile($tar_path);

Если ваш tar-файл действительно gzip-файл, используйте взамен «application / x-gtar».

Если файл все еще выходит поврежденным после загрузки, сделайте некоторую проверку на стороне клиента:

  1. Загруженный файл равен 0 байтам, но процесс загрузки, похоже, занял намного больше времени, чем 0 байтов для передачи, тогда это что-то на стороне клиента, препятствующее загрузке. Вирусный сканер? Trojan?
  2. Загруженный файл присутствует частично, но меньше оригинала? Что-то убило передачу преждевременно. Перегрузить брандмауэр? У менеджера загрузок плохой день? Буферизация вывода активна на сервере и последний буферный буфер не очищен должным образом?
  3. Имеет ли загруженный файл такой же размер, как и у оригинала? Сделайте контрольную сумму md5 / sha1 / crc на обеих копиях. Если они одинаковы, значит что-то не так с приложением, открывающим файл, а не с самим файлом
  4. Загруженный файл больше оригинала? Откройте файл в блокноте (или что-то лучше, например notepad ++, который не требует много лет, чтобы открывать большие файлы) и посмотрите, были ли какие-либо предупреждения PHP или невидимые пробелы, которые вы не видите в своем скрипте, были вставлены в загрузку в начале или конец файла.
5 голосов
/ 04 августа 2010

Я использовал этот код, когда мне пришлось это сделать:

function _Download($f_location, $f_name){
 header('Content-Description: File Transfer');
 header('Content-Type: application/octet-stream');
 header('Content-Length: ' . filesize($f_location));
 header('Content-Disposition: attachment; filename=' . basename($f_name));
 readfile($f_location);
 }

_Download("../directory/to/tar/raj.tar", "raj.tar");
//or
_Download("/var/www/vhost/domain.com/httpdocs/directory/to/tar/raj.tar", "raj.tar");

Попробуйте это.

1 голос
/ 04 августа 2010

Использовать Content-Type: application / octet-stream или Content-Type: application / x-gtar

1 голос
/ 04 августа 2010

Попробуйте что-то вроде следующего:

$s_filePath = 'somefile.ext';
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'. s_filePath.'"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
header('Cache-control: private');
header('Pragma: private');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header("Content-Length: ".filesize($s_filePath));

$r_fh = fopen($s_filePath,'r');
while(feof($r_fh) === false) {
    $s_part = fread($r_fh,10240);
    echo $s_part;
}
fclose($r_fh);
exit();
0 голосов
/ 03 июня 2018

Убедитесь, что вы не повторяете ничего, кроме вывода файла. Вызовите ob_clean () перед заголовками

...