下载zip文件前打印html

时间:2018-05-22 10:09:51

标签: php symfony buffer flush

你好编码员!

我正在寻找一个显示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;

第二次编辑:我理解我正在尝试做的事情(在一次通话中更改内容类型)我一般不赞成。我目前正在尝试考虑更优雅的解决方案。

3 个答案:

答案 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