Как отдать файл на скачивание в фреймворке yii2?

146
02 декабря 2020, 17:40

У меня есть такой пост запрос

 $.ajax({
            type   : 'POST',
            cache  : false,
            url    : '*****',
            data   :  'fghfghfgh',
            success: function(data) {
                if (data === 'ok')
                {
                  console.log('~~~~~~~1~~~',data)
                }
                else
                {
                    var link = document.createElement('a');
                    link.setAttribute('href',data);
                    link.setAttribute('download','download');
                    link.click();
                    // console.log('~~~~2~~~~~~',data)
                }
            }
        });

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

  public function actionDownload()
        {
            \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
            $model = new Converter();
            if (Yii::$app->request->post()) {
           .....
            }
            $file = Yii::getAlias('@backend/uploads/uploadslocal_9i5xxzsgrujvedvtbo.jpg');
            return Yii::$app->response->sendFile($file);
        }

Как мне сделать что бы файл не отправлялся ответом обратно, а начинал скачиваться ?

Answer 1

Action для загрузки. Код по свои нужды можете поправить.

    /**
     * @param $filename string      Название файла
     * @param $expansion string     Расширение файла
     *
     * @return string
     */
    public function actionDownload($filename, $expansion) {
        $filePath = '../uploads/' . $filename . '.' . $expansion;
        if (file_exists($filePath)) {
            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            $mime  = finfo_file($finfo, $filePath);
            finfo_close($finfo);
            $size  = filesize($filePath);
            header("Content-Type: ".$mime);
            header("Content-Length: ".$size);
            header("Content-Disposition: attachment; filename=\"" . $filename . '.' . $expansion . "\"");
            readfile($filePath);
        } else {
            throw new CHttpException(404, 'Файл не найден');
        }
        exit;
    }

На стороне js есть смысла при успешном запросе делать редирект на ссылку загрузки или использовать, например, jQuery File Download.

Answer 2

Если это вам поможет, в методе контроллера (в моем случае это фреймворк CodeIgniter) мы задаем заголовок документа через php, в котором и говорим что ответом выполнения скрипта является бинарный файл, после наполняем его данными (здесь я подгружаю картинку и наношу на неё текст) и браузер видя эти данные распознает я так понял их как совместимый файл где и предлагает сохранить его на ПК.

READ ALSO
Как уменьшить нагрузку на веб сервер

Как уменьшить нагрузку на веб сервер

Имеется php скрипт который в цикле выполняет поиск записей по БД и запускается кроном каждую минутуОдна итерация цикла проходит примерно...

120
Google recaptcha

Google recaptcha

Как сделать обьязательным поле google recaptcha? Например если пользователь не прошел капчу то кнопка отправить не работает

103