PHP Content-Length标头不起作用

时间:2014-01-11 16:48:48

标签: php http-headers http-content-length

我正在尝试使用此代码下载.zip文件

<?php
    $file = "something.zip";
    $size = filesize($file);
    header('Content-type: application/octet-stream');
    header("Content-length: $size");
    header('Content-Disposition: attachment; filename="downloaded.zip"');
    readfile($file);
?>

但它似乎不起作用,即使我尝试将文件大小设置为header("Content-length: 567247784");之类的数字。我只得到一个没有声明大小的文件,或者一个28字节的小文件。

我查看了this问题,我认为我和海报有同样的问题,但他的解决方案是“存在服务器问题”。我想我也有服务器配置问题,但他的回答根本没有帮助我。

6 个答案:

答案 0 :(得分:12)

它与mod_deflate阻碍相关。我花了一天时间搞乱.htaccess并尝试了一百万种不同的东西,最后修复了它,但我无法解释原因:

    header('Content-Length: '.$filesize);
    header("Content-Range: 0-".($filesize-1)."/".$filesize);

我想补充说我的PHP配置了少于256MB的内存。

答案 1 :(得分:0)

尝试在这种情况下删除尾随?>?>之后的换行符或空格可以改变结果。

通常,网络服务器会自动设置Content-Length标头。

对于调试,您可以使用非常棒的http://fiddler2.com/来检查标头,甚至可以组成一个任意请求来测试您的假设。如果内容正文与Content-Length标题不同,Fiddler会发出警告。

答案 2 :(得分:0)

我认为最简单,最好的方法是:

$head = array_change_key_case(get_headers($file, TRUE));
                    $filesize = $head['content-length'];

答案 3 :(得分:0)

根据TeeraMusic的出色分析https://stackoverflow.com/a/30569921/820841,该分析确定了mod_deflate是罪魁祸首?


选项1 :(对此请求禁用DEFLATE)

apache_setenv('no-gzip', '1');

停止此请求的正确方法。


选项2 :(对此内容类型的所有请求均禁用DEFLATE)

控制哪些文件为DEFLATE的选项很可能位于您的.htaccesshttpd.conf中:

AddOutputFilterByType DEFLATE "application/atom+xml" \
                              "application/javascript" \
                              ...
  1. 确保您实际上为响应设置了正确的Content-Type,而不仅仅是匹配text/html
  2. 如果您不希望将特定的Content-Type通过mod_deflate传递,请从该列表中删除。

答案 4 :(得分:-1)

也许这个问题: header("Content-length:" . $size); 但我可能是错的

答案 5 :(得分:-1)

我遇到了同样的问题,在我的情况下,当我在一些php文件中发现<?php标记之前包含一个转义符时,它就解决了。然后,返回的页面大于$size = filesize($file);中的通知,这会导致错误。