【问题标题】:headers to force the download of a tar archive用于强制下载 tar 存档的标头
【发布时间】:2010-08-04 08:26:34
【问题描述】:

我在服务器上有一个 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>

并且下载工作正常,所以我确定标题中缺少某些内容。

【问题讨论】:

  • 使用filesize函数不是更好吗?
  • 同样的事情,但我必须使用 die
  • 您是否可能超过了 max_execution_time、post_max_size 或 upload_max_filesize?
  • 不,我看不到任何错误
  • 在标准文本编辑器中检查下载的文件,查看文件内容中是否有任何 PHP 错误消息(例如,标头已发送)

标签: php download header tar


【解决方案1】:

当我不得不这样做时,我使用了这段代码:

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");

试试看。

【讨论】:

  • 我试过了,但结果是一样的。我认为编码头缺少一些东西。
  • 其他文件下载是否正常,例如图像。我现在正在本地为你测试
  • 好吧,我扔给它的任何文件似乎都对我有用:-|你怎么称呼这个文件?比如直接点赞localhost/download.php
  • 遇到了类似的问题。原来php在文件之前发送了一些额外的数据。我在调用 readfile 之前添加了对“ob_clean()”的调用 - 现在它可以工作了。
【解决方案2】:

不要使用file_get_contents() 然后echoprint 来输出文件。这会将文件的全部内容加载到内存中。大文件可以/将超过您脚本的 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 字节所需的时间要长得多,那么这是客户端阻止下载的原因。病毒扫描器?木马?
  2. 下载的文件是否部分存在,但比原始文件小?某些东西过早地终止了转移。过火的防火墙?下载管理器有糟糕的一天?服务器上的输出缓冲处于活动状态,并且最后一个缓冲桶未正确刷新?
  3. 下载的文件和原来的大小一样吗?对两个副本执行 md5/sha1/crc 校验和。如果它们相同,则说明打开文件的应用程序有问题,而不是文件本身
  4. 下载的文件比原来的大吗?在记事本中打开文件(或者像记事本++这样更好的东西,它不需要几年来打开大文件),看看是否有任何 PHP 警告消息,或者你在脚本中看不到的一些不可见的空白在开始时被插入到下载中或文件结尾。

【讨论】:

    【解决方案3】:

    尝试以下方法:

    $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();
    

    【讨论】:

    • 同样的结果。我认为编码头有问题。
    【解决方案4】:

    使用 Content-Type:application/octet-stream 或 Content-Type:application/x-gtar

    【讨论】:

      【解决方案5】:

      确保您没有回显任何不是文件输出的内容。在标题前调用 ob_clean()

      【讨论】:

        猜你喜欢
        • 2017-03-30
        • 1970-01-01
        • 2023-03-07
        • 2023-04-01
        • 1970-01-01
        • 2020-06-08
        • 1970-01-01
        • 2023-04-09
        • 1970-01-01
        相关资源
        最近更新 更多