你好编码员!
我正在寻找一个显示html页面的解决方案,而我的php代码准备一个.zip然后下载。原因是因为有时拉链比较大,需要时间。
HTML页面将是一个基本的“请等待您的.zip文件正在准备中”。 使用的PHP方面是Symfony。所以我通过调用https://myapi.com/orders/orderid/inbox/export进入我的getInboxExportAction函数。
下载功能(makeExportDownloadRequestResponse)运行正常。但是如果我在做出我的$响应之后添加了一个flush,那么.zip将被打印到html,而不是被下载...
public function getInboxExportAction(Request $request, $orderId)
{
$response = new Response($this->twig->render('base.html.twig',
['content' => '
<h1>Download</h1>
<p>Your zip is being prepared for download, please wait...</p>
']));
$response->headers->set('Content-Type', 'text/html');
//Here I would like to echo + flush my html.
//Then stop the flush and continue my code
$receivedOrder = $this->fetchRequestedReceivedOrder($orderId);
if (!$receivedOrder instanceof ReceivedOrder) {
return $receivedOrder;
}
if (!$receivedOrder->getSentorder()) {
$this->makeErrorResponse('Sent order was not found', Response::HTTP_BAD_REQUEST);
}
return $this->makeExportDownloadRequestResponse($receivedOrder->getSentorder(), $request->get('format'));
}
我也很乐意接受任何其他想法来解决这个问题的想法:)
谢谢,
编辑:我的$ this-&gt; makeExportDownloadRequestResponse()函数返回响应,而不是路径。出于存储原因,我们取消了服务器上的文件链接。
$content = file_get_contents($zipTmpFile);
unlink($zipTmpFile);
$response = new Response($content);
$dispositionHeader = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT,
'myFile_' . date('Y_m_d_h_i_s') . '.zip');
$response->headers->set('Content-Disposition', $dispositionHeader);
return $response;
第二次编辑:我理解我正在尝试做的事情(在一次通话中更改内容类型)我一般不赞成。我目前正在尝试考虑更优雅的解决方案。
答案 0 :(得分:1)
在getInboxExportAction
中,只需返回包含文字的回复。
然后,在此响应中,添加<meta http-equiv="refresh" content="1;url=xxx">
标记以将用户重定向到将生成zip文件的另一个操作。
您也可以使用javascript处理此重定向。
请注意,您可以使用StreamedResponse
来处理zip下载:https://symfony.com/doc/current/components/http_foundation.html#streaming-a-response
答案 1 :(得分:0)
最重要的是你设置const LOCATIONS_QUERY = gql`
query LocationsQuery {
locationsInRadius @algolia(index: "dev_LOCATIONS", aroundLatLng: "40.71, -74.01", aroundRadius: 1000)
}
`
,浏览器不会下载.zip文件。
如果您的$response->headers->set('Content-Type', 'text/html');
方法可以返回绝对.zip文件路径(或者您可以计算它),您可以尝试:
makeExportDownloadRequestResponse
它会让浏览器下载zip文件。
最后,如果您的函数作为API工作,并且您需要前端JS来执行它,请尝试使用JS上的public function getInboxExportAction(Request $request, $orderId)
{
$response = new Response($this->twig->render('base.html.twig',
['content' => '
<h1>Download</h1>
<p>Your zip is being prepared for download, please wait...</p>
']));
$response->headers->set('Content-Type', 'text/html');
//Here I would like to echo + flush my html.
//Then stop the flush and continue my code
$receivedOrder = $this->fetchRequestedReceivedOrder($orderId);
if (!$receivedOrder instanceof ReceivedOrder) {
return $receivedOrder;
}
if (!$receivedOrder->getSentorder()) {
$this->makeErrorResponse('Sent order was not found', Response::HTTP_BAD_REQUEST);
}
// prepare the to be downloaded zip file
// then, do sth to get the .zip file path
$zipFilePath = $this->makeExportDownloadRequestResponse($receivedOrder->getSentorder(), $request->get('format'));
// re-set header
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename=whateverName.zip');
header('Content-Length: ' . filesize($zipFilePath));
readfile($zipFilePath);
}
类。
答案 2 :(得分:0)
您确实可以使用StreamedResponse来摆脱这个问题。关于整个.wip文件内容因为刷新而显示的事实,尝试在之前调用 ob_flush