Vue + Laravel: Как правильно загрузить файл PDF? - PullRequest
0 голосов
/ 07 июня 2018

СИТУАЦИЯ:

Внешний интерфейс: Vue.Серверная часть: Laravel.

Внутри веб-приложения мне нужно разрешить пользователю загружать определенные PDF-файлы:

  • Мне нужно, чтобы Laravel взял файл и возвратил его как ответ APIGET request.
  • Затем внутри моего веб-приложения Vue мне нужно получить файл и загрузить его.

КОД:

API:

$file = public_path() . "/path/test.pdf";

$headers = [
    'Content-Type' => 'application/pdf',
];
return response()->download($file, 'test.pdf', $headers);

Веб-приложение:

downloadFile() {
  this.$http.get(this.apiPath + '/download_pdf')
    .then(response => {
      let blob = new Blob([response.data], { type: 'application/pdf' })
      let link = document.createElement('a')
      link.href = window.URL.createObjectURL(blob)
      link.download = 'test.pdf'
      link.click()
    })
}

РЕЗУЛЬТАТ:

Использование этогокод мне удается скачать PDF-файл.Проблема в том, что PDF пуст.

Каким-то образом данные были повреждены (не проблема этого конкретного файла PDF, я пытался с несколькими файлами PDF - тот же результат)

ОТВЕТ ОТ СЕРВЕРА:

Сам ответ с сервера в порядке:

enter image description here

PDF:

Проблемаможет быть с файлом PDF.Это определенно выглядит поврежденные данные.Вот выдержка из того, как выглядит response.data:

enter image description here

ВОПРОС:

Как правильно загрузить PDF-файл, используя Laravel для API и Vue для веб-приложения?

Спасибо!

Ответы [ 3 ]

0 голосов
/ 07 июня 2018

РЕШЕНИЕ:

Должные кредиты отправляются @Sagar, чтобы указать мне правильное направление.

Код выше был верным.Чего не хватало, так это добавления правильных responseType как arraybuffer.

. Я испугался этих ???? в ответе, и это вводило меня в заблуждение.Эти вопросительные знаки были в порядке, так как pdf является двоичными данными и предназначен для чтения надлежащим читателем.

Массив:

И массив буферов точно используется длясохраняйте двоичные данные.

Это определение с веб-сайта mozilla:

Объект ArrayBuffer используется для представления общего буфера исходных двоичных данных фиксированной длины.Вы не можете напрямую манипулировать содержимым ArrayBuffer;вместо этого вы создаете один из объектов типизированного массива или объект DataView, который представляет буфер в определенном формате, и используете его для чтения и записи содержимого буфера.

И ResponseTypeСтрока указывает тип ответа.Сказав свой массив буферов, он затем обрабатывает данные соответствующим образом.

И просто добавив responseType, мне удалось правильно загрузить файл PDF.

КОД:

Это исправленный код Vue (точно так же, как и раньше, но с добавлением responseType):

downloadFile() {
  this.$http.get(this.appApiPath + '/testpdf', {responseType: 'arraybuffer'})
    .then(response => {
      let blob = new Blob([response.data], { type: 'application/pdf' })
      let link = document.createElement('a')
      link.href = window.URL.createObjectURL(blob)
      link.download = 'test.pdf'
      link.click()
    })
}

РЕДАКТИРОВАТЬ:

Этоболее полное решение, учитывающее поведение других браузеров:

downloadContract(booking) {
  this.$http.get(this.appApiPath + '/download_contract/' + booking.id, {responseType: 'arraybuffer'})
    .then(response => {
      this.downloadFile(response, 'customFilename')
    }, response => {
      console.warn('error from download_contract')
      console.log(response)
      // Manage errors
      }
    })
},

downloadFile(response, filename) {
  // It is necessary to create a new blob object with mime-type explicitly set
  // otherwise only Chrome works like it should
  var newBlob = new Blob([response.body], {type: 'application/pdf'})

  // IE doesn't allow using a blob object directly as link href
  // instead it is necessary to use msSaveOrOpenBlob
  if (window.navigator && window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(newBlob)
    return
  }

  // For other browsers:
  // Create a link pointing to the ObjectURL containing the blob.
  const data = window.URL.createObjectURL(newBlob)
  var link = document.createElement('a')
  link.href = data
  link.download = filename + '.pdf'
  link.click()
  setTimeout(function () {
    // For Firefox it is necessary to delay revoking the ObjectURL
    window.URL.revokeObjectURL(data)
  }, 100)
},
0 голосов
/ 22 марта 2019
downloadFile: function () {
            this.$http.post('{{ route('download.download') }}', {
                _token: "{{ csrf_token() }}",
                inputs: this.inputs
            },{responseType: 'arraybuffer'}).then(response => {
                var filename = response.headers.get('content-disposition').split('=')[1].replace(/^\"+|\"+$/g, '')
                var url = window.URL.createObjectURL(new Blob([response.body],{type:response.headers.get('content-type')}))
                var link = document.createElement('a')
                link.href = url
                link.setAttribute('download', filename)
                document.body.appendChild(link)
                link.click()
            });
        },
0 голосов
/ 07 июня 2018

Вы не сможете выполнить загрузку с Laravel до Vue, так как оба работают на разных портах, я полагаю.

Даже если вы попробуете что-то подобное.

public function getDownload()
    {
        //PDF file is stored under project/public/download/info.pdf
        $file= public_path(). "/download/info.pdf";

        $headers = [
              'Content-Type' => 'application/pdf',
           ];

    return response()->download($file, 'filename.pdf', $headers);
    }

Это не поможет, так как вы отправляете заголовки в порт Laravel. Попробуйте использовать библиотеки Vue js и попробуйте отправить это содержимое PDF в библиотеку.

Попробуйте это Получите помощь отздесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...