загрузка потока ответов laravel возвращает пустой файл

У меня есть метод контроллера, который получает запрос пользователя на загрузку, вызывает конечную точку REST API с запрошенными параметрами тела.

API, в свою очередь, отправляет файл.

Я использую Guzzle для выполнения запросов API и версию laravel 5.4.

Содержимое $response->getBody()->getContents(); выглядит следующим образом:

"""
request_id\ts_sku\tr_product_url\thuman_verdict\n
199\tSG-948\thttps://www.amazon.com/gp/offer-listing/B076CP7J4P?condition=new\tMatch\n
199\tZIB-601\thttps://www.amazon.com/gp/offer-listing/B07D9PN39C?condition=new\tMatch\n
199\tRCM-LG526\thttps://www.amazon.com/gp/offer-listing/B07FDJ3W7P?condition=new\tMatch\n
199\tGSI-335\thttps://www.amazon.com/gp/offer-listing/B07GNX1VSG?condition=new\tMatch\n
199\tZIB-489\thttps://www.amazon.com/gp/offer-listing/B07D9RCGXM?condition=new\tMatch\n
"""

Также полученный ответ заголовка от API:

Content-Type : ('text/tab-separated-values', none)
Content-Disposition : attachment; filename=/path/to/file1.tsv

Я пытаюсь получить этот файл в своем контроллере и вернуть ответ в виде потоковой загрузки в браузер пользователя.

Вот метод контроллера:

    $client = new Client(["base_uri" => $this->apiBaseUrl]);
    $url = 'download/filterdownload/';

    try {
        $response = $client->request('POST', $url, ['headers'=>['Content-Type' => 'application/json'], 'body'=>json_encode($filterArr)]);
        # $resArr = json_decode($response, true);
    } catch (\Exception $e) {
        return redirect()->back()->with('error', $e->getMessage());
    }

    if(!empty($resArr) && array_key_exists('response', $resArr))
        return redirect()->back()->with('error', $resArr['response']);

    # return response
    $file = $response->getBody()->getContents();

    $file_name = $filterArr['client_name'].'_'.Carbon::now()->toDateString().'.tsv';
    $headers = [
        'Content-Disposition' => 'attachment; filename='. $file_name. ';'
    ];
    return response()->stream(function () {
        $file;
    }, 200, $headers);

Это загружает файл, но файл пуст.


person Azima    schedule 22.11.2019    source источник


Ответы (1)


Может поможет:

 # return response
    $file = $response->getBody()->getContents();

    $file_name = $filterArr['client_name'].'_'.Carbon::now()->toDateString().'.tsv';
    $headers = [
        'Content-Disposition' => 'attachment; filename='. $file_name. ';'
    ];
    return response()->stream(function () use ($file)  { <-- edit
        $file;
    }, 200, $headers);
person Dmitry    schedule 22.11.2019
comment
Я думаю, что это неправильный метод, поскольку вы пытаетесь использовать потоковый ответ с содержимым файла. Чтобы сделать это правильно, вам нужно использовать что-то вроде readfile($file_full_path) в ответе, например: return response()->stream(function () use ($full_file_path) { readfile($full_file_path); }, 200 , $headers); Теперь это должно работать, я говорю это, потому что я пробовал этот метод для загрузки .zip-архива, и он не работал, с той правкой, которую я только что предложил, - работает нормально . Подробнее о readfile() читайте здесь - php.net /manual/ru/function.readfile.php - person Taras Chernata; 14.01.2021
comment
Это все еще возвращает пустой файл для меня. - person Carol-Theodor Pelu; 15.06.2021