【问题标题】:Print html before downloading zip file在下载 zip 文件之前打印 html
【发布时间】:2018-05-22 10:09:50
【问题描述】:

各位程序员您好!

我正在寻找一种解决方案来显示一个 html 页面,而我的 php 代码会准备一个 .zip,然后下载它。原因是有时拉链会很大,而且制作起来需要时间。

HTML 页面将是一个基本的“正在准备您的 .zip 文件,请稍候”。 使用的 PHP 端是 Symfony。所以我通过调用https://myapi.com/orders/orderid/inbox/export 进入我的getInboxExportAction 函数。

下载功能 (makeExportDownloadRequestResponse) 工作正常。但是,如果我在 $response 后添加一个刷新,.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->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;

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

【问题讨论】:

    标签: php symfony buffer flush


    【解决方案1】:

    在您的getInboxExportAction 中,只需使用您的文字返回回复即可。

    然后,在此响应中,添加 &lt;meta http-equiv="refresh" content="1;url=xxx"&gt; 标记以将用户重定向到另一个将生成 zip 文件的操作。

    您也可以使用 javascript 处理此重定向。

    请注意,您可以使用StreamedResponse 来处理 zip 下载:https://symfony.com/doc/current/components/http_foundation.html#streaming-a-response

    【讨论】:

    • 感谢您的解决方案,这听起来很不错。虽然我不能在我的项目中使用它,但我会再保留它。
    【解决方案2】:

    最重要的是你设置了$response-&gt;headers-&gt;set('Content-Type', 'text/html');,浏览器不会下载.zip文件。

    如果你的makeExportDownloadRequestResponse方法可以返回绝对的.zip文件路径(或者你可以计算出来),你可以试试:

    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);
    }
    

    它会让浏览器下载压缩文件。

    最后,如果您的函数作为 API 工作,并且您需要前端 JS 来执行它,请尝试在 JS 上使用 Blob 类。

    【讨论】:

      【解决方案3】:

      您确实可以使用 StreamedResponse 来解决这个问题。关于由于刷新而显示整个.wip文件内容的事实,请尝试在

      之前调用ob_flush

      【讨论】:

      • 我无法更改 StreamedResponse 中的内容类型,但感谢提交 :)
      猜你喜欢
      • 1970-01-01
      • 2021-09-24
      • 2016-02-25
      • 1970-01-01
      • 1970-01-01
      • 2018-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多