【问题标题】:File download using BinaryFileResponse works for a while, then fails使用 BinaryFileResponse 的文件下载工作了一段时间,然后失败
【发布时间】:2021-11-10 16:41:34
【问题描述】:

我使用此功能从我的服务器下载 MP3 文件;这些文件有几兆,大小在 1 到 10 兆之间。它工作得很好,但是它会在一段时间后停止工作,然后每当我们使用该功能时它都会永久引发错误(catch 部分),直到我重新启动 Web 服务器。一旦我重新启动它,它就会恢复正常运行。 Web 服务器是 OpenLiteSpeed 1.4。

请告知我是否正确使用 BinaryFileResponse 函数?

function getFile($user_id, $filename)
{
    if (empty($filename)) {
        throw new \InvalidArgumentException('Please provide a valid filename.');
    } else {
        $filepath = "../files/$filename";

        BinaryFileResponse::trustXSendfileTypeHeader();

        try {
            $response = new BinaryFileResponse($filepath);

            $mimeTypes = new MimeTypes();
            $mimeType = $mimeTypes->guessMimeType($filepath);

            $response->headers->set('Content-Type', $mimeType);
            $response->setAutoEtag();
            $response->setContentDisposition(
                ResponseHeaderBag::DISPOSITION_ATTACHMENT,
                $filename
            );
        } catch (FileNotFoundException $exception) {
            $response = new JsonResponse(
                ['Status' => 'Error', 'Message' => DEBUG ? $exception->getMessage() : 'File not found.'],
                Response::HTTP_NOT_FOUND
            );
        }
    }

    return $response;
}

【问题讨论】:

  • 这是 Symfony,对吧?完全删除try/catch,以便您可以看到完整的异常。
  • 好的,谢谢,所以我实际上得到了 {"Status":"Error","Message":"The filename and the fallback cannot contain the \u0022\/\u0022 and \u0022\\\ u0022 个字符。”}。我将看看如何拆分路径并传递单个参数
  • 你能把它变成你自己接受的答案吗?
  • 我快到了;据我了解,该错误与 $filename 在作为 setContentDisposition 的第二个参数传递时包含 / 相关。然后我添加了 $filename = basename($filepath);以前但现在浏览器会抛出无效响应,即使文件名是干净的。我检查了 $mimeType 并将其正确设置为音频/mpeg,因此这意味着它至少能够找到有问题的文件。使用或不使用 try/catch 时,结果是一样的。有什么想法吗?

标签: php openlitespeed


【解决方案1】:

我搜索了几个小时,但找不到答案,所以我决定采用一种完全不同的方法,效果很好:

$filename = basename($filepath);

set_time_limit(0);
ini_set('memory_limit', '25M');

while (ob_get_level()) ob_end_clean();
header('Content-Type: audio/mpeg');
header('Content-Disposition:  attachment; filename=' . basename($filepath));
header('Cache-Control: no-cache');
header("Content-Transfer-Encoding: chunked");
ob_flush();
flush();
readfile($filepath);
exit;

【讨论】:

    猜你喜欢
    • 2016-04-24
    • 2020-05-03
    • 2015-04-16
    • 1970-01-01
    • 1970-01-01
    • 2018-10-21
    • 2014-05-17
    • 1970-01-01
    • 2011-05-21
    相关资源
    最近更新 更多