【问题标题】:xsendFile downloads have 0 bytesxsendFile 下载有 0 个字节
【发布时间】:2014-03-19 14:04:51
【问题描述】:

在 LAMP 堆栈上,我无法让 xSendFile 工作。问题是下载有 0 个字节。

为了确保我安装了 xSendFile,我已将此添加到我的 .htaccess 文件中:

<IfModule mod_xsendfile.c>
  SetEnv MOD_mod_xsendfile 1
</IfModule>

(我无法用apache_get_modules() 测试这个,因为我将 PHP 作为 fastCGI 运行。)

然后我有以下 PHP 代码:

 if (1 != getenv('MOD_mod_xsendfile'))
    {
        echo 'mod_xsendfile is not installed';
    }
    else
    {
        $path = '/home/infar/';
        $file = 'hello.txt';
        if (file_exists($path.$file) && strlen($path.$file)>1)
        {
            if (true) // change to false to go around Yii
            {
                Yii::app()->request->xSendFile($path.$file,array(
                    'saveName'=> 'hello.txt',
                    'mimeType'=> 'plain/text',
                    'terminate'=> true,
                ));
            }
            else
            {
                //set proper Content-Type
                header('Content-Type: plain/text');
                //force download box with the filename hello.txt
                header('Content-Disposition: attachment;filename=hello.txt');
                header('X-Sendfile: $path.$file');
                exit;      
            }  
        }
        else
        {
            echo 'file not found at: '.$path.$file;
        }
    }

此代码按预期运行;我从中得出结论,必须安装和/或启用 xSendFile。然后我使用 Yii xSendFile 和普通 PHP 运行这个脚本。在这两种情况下,下载窗口都会打开,但始终为 0 字节。

我束手无策。 我做错了什么?

为了充分披露,这里是httpd.conf的相关部分:

<IfModule mod_xsendfile.c>
    XSendFile on
    XSendFilePath /home/infar
</IfModule>

编辑:

输出压缩已关闭:

ini_get("zlib.output_compression"); // returns "Off"

Chrome 显示以下标题:

Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:Keep-Alive
Content-Disposition:attachment;filename=hello.txt
Content-Length:0
Content-Type:plain/text
Date:Sun, 23 Mar 2014 18:22:49 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive:timeout=2, max=100
Pragma:no-cache
Server:Apache
X-Sendfile:/home/infar/hello.txt

2014 年 3 月 26 日更新

在测试@gabrieloliveira 的建议时,我发现了以下内容:

header('Content-Type: plain/text');
header('Content-Disposition: attachment;filename=hello.txt');
header('X-Sendfile: '.$path.$file); // $path.$file outside quotes
header('Content-Length: '.filesize($path.$file)); // Filesize
echo '12345678901234567890';
exit;  

这个脚本(我在其中添加了echo '12345678901234567890';)生成了一个包含以下16 个字符串1234567890123456 的文件的下载。 16 个字符与 hello.txt 的文件大小匹配。所以看来我们可以得出以下结论

  1. 正确处理内容长度和文件大小。
  2. 要么 X-SendFile 找不到文件,要么:
  3. X-SendFile 不处理文件。

其实注释掉X-SendFile,就像这样:

// header('X-Sendfile: '.$path.$file);

产生相同的结果;从执行X-Sendfile 标头时听不见。

【问题讨论】:

  • 你有没有想过这个问题?我也遇到了同样的问题。
  • 不,从来没有弄清楚。我只是放弃了。抱歉,我无法提供更多帮助。我得出的结论是,我的主机(我在 Dreamhost)所做的事情让这变得不可能......
  • 任何解决方法?在我们转移到新服务器之前,它曾经与我的托管服务提供商(认证托管)合作。他们声称这是一个脚本问题,我认为服务器配置错误。我似乎也无法让它与 readfile() 一起使用。当然,我有一个 .htaccess 文件来阻止来自非域的引用者的请求,但我怀疑这是问题所在。

标签: php yii x-sendfile


【解决方案1】:

用纯PHP编辑这部分测试:

header('Content-Type: plain/text');
//force download box with the filename hello.txt
header('Content-Disposition: attachment;filename=hello.txt');
header('X-Sendfile: '.$path.$file); // $path.$file outside quotes
header('Content-Length: '.filesize($path.$file)); // Filesize

编辑:

尝试改变:

header('application/octet-stream');

【讨论】:

  • 恐怕这会给出相同的结果:0 字节。然而,我又玩了一些,得到了一些可能很有趣的结果。请参见上文。
  • 我编辑了答案。我不确定 xsendfile 是否必须在没有 readfile() 的情况下发送输出,但我相信使用 readfile() 他会播放要下载的输出文件。
  • 我再次编辑,尝试将内容类型编辑为 application/octet-stream
  • header('Content-Type: application/octet-stream'); 这样更改内容类型仍然给出相同的结果:0 字节
  • 是的,它指向/home/infar/hello.txt。并且脚本会验证文件是否存在...
【解决方案2】:

确保要提供的文件的路径与您在 httpd.conf 或 httpd-vhosts.conf 上的 XSendFilePath 指令中使用的路径相同

或者:您是否发送公共文件夹之外的文件?如果是这样,那么将 XSendFileAllowAbove 添加到 apache 配置中

【讨论】:

  • 谢谢。我正在尝试从 webroot 外部发送文件。我的XSendFilePath/home/infar。无论我尝试从该目录发送文件还是它的子目录都没有区别:始终为 0 字节。据我了解,XSendFileAllowAbove 已被弃用。
  • 你说得对,它已被弃用。我还从 webroot 外部传递文件,并设法通过在传递文件后简单地使用相同的路径来使其工作。如果您可以让 Chrome 告诉您请求的标头,您就可以知道正在传递哪个文件/路径。
  • 我已经添加了 Chrome 显示的标题。在我看来没问题。 Chrome 确实告诉我 GET 请求的状态为“(已取消)”
  • ... 而 Firefox 向我保证同一个请求的状态为 200 OK。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2019-06-16
  • 2021-08-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多