Symfony 3.4 - 将 API 流文件传输到客户端下载

Posted

技术标签:

【中文标题】Symfony 3.4 - 将 API 流文件传输到客户端下载【英文标题】:Symfony 3.4 - Transfert API stream file to client download 【发布时间】:2021-03-09 12:43:10 【问题描述】:

API 向我发送了一个流,其中包含几个文件的 zip 存档,我通过在我的请求的参数 SelectedIds 中提供它们的 ID 来选择这些文件。 我收到一个 PSR7 响应,我将它传递给 HttpFoundationFactory 以返回与 Symfony 控制器应返回的内容相对应的响应。

(目标是在客户端浏览器中下载 zip。)

这是我的控制器方法的内容

$client  = $this->getApiClient();
$user    = $this->getUser();
$idList  = [51,52,53];
$psr7ApiResponse = $client->post('/v1/get-zip', [
    'headers'     => [
        'Authorization' => sprintf('Bearer %s', $user->getToken()),
    ],
    'http_errors' => false,
    'json'        => [
        'SelectedIds' => $idList,
    ],
]);

$httpFoundationFactory = new HttpFoundationFactory();
return $httpFoundationFactory->createResponse($psr7ApiResponse);

它在本地完美运行,但在服务器上我什么也没收到,空白页。你知道我应该怎么看吗,因为我没有错误日志,看起来流是空的,但我不知道如何检查。

我用邮递员测试了API,没问题;我的控制器也给我发回了 200

【问题讨论】:

您是否尝试在生产环境中将 http_errors 设置为 true? 是的,没有错误一切正常:'(但响应似乎是空的 $psr7ApiResponse 里面是什么?它应该包含一个状态代码和一些希望有更多信息的标题。您是否完全打开了 php 中的错误报告? 我真的没有错误,它在本地运行得很好,但不是在线。所有状态码都是 200。很难调试。当我将提要的内容传输到浏览器时,它似乎没有完全返回到我的后端 同一个 API 中是否还有其他不下载 ZIP 的函数(例如简单的 GET 或 POST),您可以在 PROD 上进行测试,以确定 API 是否存在问题一个整体,还是孤立于这个特定的过程?如果是前者,还要确认您的 API 端点没有 IP 白名单限制阻止它发送您的产品服务器响应。您能否在$psr7ApiResponse 内发布回复。 【参考方案1】:

按照这些步骤来调试问题:

1.检查$psr7ApiResponse的内容是否有效且正确

您处于不同的环境中。也许由于某种原因,您的服务器端脚本没有收到有效的答案。也许身份验证不起作用。根据需要将收到的答案打印到一些日志文件中(使用记录器: https://symfony.com/doc/current/logging.html)。

如果调用的内容或结果类不正确,则问题出在远程调用通信中,您必须对其进行调试。很可能是这种情况。

2。检查您的客户是否真的理解答案并检查答案是否正确

你的客户肯定不会收到空白页(它表示问题是1)。

尝试使用Symfony\Component\HttpFoundation\File\File 显式返回文件。

您还可以手动将某些 ZIP 标头设置为 Response 对象 - 至少用于调试:

    // set example variables
    $filename = "zip-to-download.zip";
    $filepath = "/path"; // maybe save the response to a temp file for debugging purposes
    
    $response = $httpFoundationFactory->createResponse($psr7ApiResponse);
    $response->headers->set('Pragma','public');
    $response->headers->set('Expires',0);
    $response->headers->set('Cache-Control','must-revalidate, post-check=0, pre-check=0');
    $response->headers->set('Content-Description','File Transfer');
    $response->headers->set('Content-type','application/octet-stream');
    $response->headers->set('Content-Disposition','attachment; filename="'.$filename.'"');
    $response->headers->set('Content-Transfer-Encoding','binary');
    return $response;

【讨论】:

以上是关于Symfony 3.4 - 将 API 流文件传输到客户端下载的主要内容,如果未能解决你的问题,请参考以下文章

如何将令牌存储作为参数传递给 Symfony 3.4 中的事件监听器

Hwi oauth bundle 和 Symfony 3.4 无法自动装配服务:如何在 symfony 3.4 + FOSUserBundle 中使用 hwi/oauth-bundle

从 Symfony 3.4 升级到 4:升级 symfony 时出错

SonataUserBundle 和 Symfony 3.4

在命令 symfony 3.4 上获取项目目录

Symfony LTS:如何从 3.4 升级到 4.4?