Напечатайте html перед загрузкой zip-файла - PullRequest
0 голосов
/ 22 мая 2018

Привет, товарищи кодеры!

Я ищу решение для отображения html-страницы, пока мой php-код готовит ZIP-файл, который затем загружается.Причина в том, что иногда почтовые индексы довольно большие и занимают много времени.

HTML-страница будет простой «Пожалуйста, подождите, пока ваши .zip файлы готовятся».Используемая сторона PHP - Symfony.Поэтому я захожу в свою функцию getInboxExportAction, вызывая https://myapi.com/orders/orderid/inbox/export.

Функция загрузки (makeExportDownloadRequestResponse) работает нормально.Но если я добавлю флеш после того, как сделаю ответ в $, 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;

Второе редактирование: я понимаю, что то, что я пытаюсь сделать (изменить тип контента в течение одного вызова), я в целом нахмурился.В настоящее время я пытаюсь придумать более элегантное решение.

Ответы [ 3 ]

0 голосов
/ 22 мая 2018

Самое важное, что вы установили $response->headers->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);
}

Это позволит браузеру загрузить zip-файл.

Наконец, если ваша функция работает как API, и вам нужен JS-интерфейс для ее выполненияпопробуйте с Blob классом на JS.

0 голосов
/ 22 мая 2018

Вы действительно можете использовать StreamedResponse, чтобы избавиться от этой проблемы.По поводу того, что весь файл .wip отображается из-за сброса, попробуйте позвонить ob_flush до

0 голосов
/ 22 мая 2018

В вашем 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

...