【问题标题】:Response headers overridden when sending binary data发送二进制数据时覆盖响应标头
【发布时间】:2013-12-07 19:21:51
【问题描述】:

问题的背景 我正在使用 jPlayer 在 ZF2 应用程序中播放一些音频文件。 jPlayer 使用 ZF2 动作作为音频源,效果很好。从控制器操作中,我使用 Response 对象发回原始响应。简化后的代码如下所示:

public function streamAction()
{
    // ... left out code to retrieve order and error handling stuff ... //
    $response = $this->getResponse();
    $path = $this->orderService->getFullPathToAudioFile($order);
    $response->setStatusCode(Response::STATUS_CODE_200);
    $response->getHeaders()->addHeaderLine('Content-Type', 'audio/mpeg')
                            ->addHeaderLine('Content-Length', filesize($path))
                            ->addHeaderLine('Expires', -1)
                            ->addHeaderLine('Cache-Control', 'no-store, no-cache, must-revalidate');

    $response->setContent(readfile($path));

    return $response;
}

在 Chrome jPlayer 的 HTML5 实现中,使用它作为音频源没有问题。 Firefox 自动回退到 jPlayer 的 Flash 实现,并且工作正常。 Safari 也使用 HTML5 实现,但有一个问题,但当我使用 jPlayer 的 Flash 实现时工作正常。

这促使我查看响应中实际发送回的标头。我用 Firebug 来检查这个。我注意到这里有些奇怪:Content-Length 标头没有被发回,Content-Type 是“text/html”,而不是我指定的“audio/mpeg”。

测试代码 我做了一个小testAction来演示:

public function testAction()
{
    $path = './data/audio/test.mp3';

    $response = $this->getResponse();
    $response->setStatusCode(Response::STATUS_CODE_200);

    $response->getHeaders()->addHeaderLine('Content-Type', 'audio/mpeg')
                           ->addHeaderLine('Content-Length', filesize($path))
                           ->addHeaderLine('Expires', -1)
                           ->addHeaderLine('Cache-Control', 'no-store, no-cache, must-revalidate');

    $response->setContent(readfile($path));

    return $response;
}

请注意 我验证可以找到音频文件。当我在浏览器中调用测试操作时,我也可以看到这一点。它显示了 mp3 文件的内容。

情节变厚 当我评论设置内容的行时: $response->setContent(readfile($path)); 我确实在响应中看到了正确的 Content-Type 标头和 Content-Length 标头。

此外,当我创建如下所示的简单纯文本响应时,它也可以正常工作。

public function testAction()
{
    $response = $this->getResponse();
    $response->setStatusCode(Response::STATUS_CODE_200);

    $response->getHeaders()->addHeaderLine('Content-Type', 'text/plain')
                           ->addHeaderLine('Content-Length', 10)
                           ->addHeaderLine('Expires', -1)
                           ->addHeaderLine('Cache-Control', 'no-store, no-cache, must-revalidate');

    $response->setContent('0123456789');

    return $response;
}

任何想法为什么会这样以及如何解决它?

【问题讨论】:

    标签: php http-headers zend-framework2 mp3


    【解决方案1】:

    您的代码的主要问题是readfile() 不会返回文件内容,它会立即将它们输出到浏览器。因此,您对响应对象所做的更改没有任何效果,因为未使用响应对象。如果您将其更改为 file_get_contents(),它可能会按您的预期工作。

    除非您正在流式传输的文件很小(

    【讨论】:

    • 太棒了,这就是整个问题。非常感谢!
    猜你喜欢
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    • 2014-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多