Force загрузить GET запрос с помощью axios

Я использую vuejs 2 + axios. Мне нужно отправить запрос на получение, передать некоторые параметры на сервер и получить PDF в качестве ответа. Сервер использует Laravel.

Так

axios.get('order-results/${id}/export-pdf', { params: { ... }})

делает успешный запрос, но не запускает принудительную загрузку, хотя сервер возвращает правильные заголовки.

Я думаю, что это типичная ситуация, когда вам нужно, скажем, сформировать отчет в формате PDF и передать некоторые фильтры серверу. Итак, как это можно сделать?

Обновить

Так что я нашел решение. Однако тот же подход не работал с аксиомами, не знаю почему, почему я использовал необработанный объект XHR. Таким образом, решение заключается в создании объекта blob и функции createUrlObject пользователя. Пример примера:

let xhr = new XMLHttpRequest()
xhr.open('POST', Vue.config.baseUrl + 'order-results/${id}/export-pdf', true)
xhr.setRequestHeader("Authorization", 'Bearer ' + this.token())
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
xhr.responseType = 'arraybuffer'

xhr.onload = function(e) {
  if (this.status === 200) {
    let blob = new Blob([this.response], { type:"application/pdf" })
    let link = document.createElement('a')
    link.href = window.URL.createObjectURL(blob)
    link.download = 'Results.pdf'
    link.click()
  }
}

Важно: вы должны иметь буфер массива в качестве типа ответа

Однако тот же код, написанный в axios, возвращает PDF, который пуст:

axios.post('order-results/${id}/export-pdf', {
  data,
  responseType: 'arraybuffer'
}).then((response) => {
  console.log(response)

  let blob = new Blob([response.data], { type: 'application/pdf' } ),
      url = window.URL.createObjectURL(blob)

  window.open(url); // Mostly the same, I was just experimenting with different approaches, tried link.click, iframe and other solutions
})

Ответ 1

Вы получаете пустой PDF, потому что данные не передаются на сервер. Вы можете попробовать передать данные, используя объект данных, как это

  axios
    .post('order-results/${id}/export-pdf', {
      data: {
        firstName: 'Fred'
      },
      responseType: 'arraybuffer'
    })
    .then(response => {
      console.log(response)

      let blob = new Blob([response.data], { type: 'application/pdf' }),
        url = window.URL.createObjectURL(blob)

      window.open(url) // Mostly the same, I was just experimenting with different approaches, tried link.click, iframe and other solutions
    })

Ответ 2

Попробуйте это: он отлично работает для меня с совместимостью с Internet Explorer 11 (createObjectURL не работает на Explorer 11)

axios({
  url: 'http://vvv.dev',
  method: 'GET',
  responseType: 'blob', // important
}).then((response) => {
  if (!window.navigator.msSaveOrOpenBlob){
    // BLOB NAVIGATOR
    const url = window.URL.createObjectURL(new Blob([response.data]));
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', 'download.pdf');
    document.body.appendChild(link);
    link.click();
  }else{
    // BLOB FOR EXPLORER 11
    const url = window.navigator.msSaveOrOpenBlob(new Blob([response.data]),"download.pdf");
  }
});

https://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743

Ответ 3

Я не думаю, что это возможно сделать в аксиомах или даже AJAX. Файл будет сохранен в памяти, т.е. Вы не сможете сохранить файл на диск. Это связано с тем, что JavaScript не может взаимодействовать с диском. Это будет серьезной проблемой безопасности, и она заблокирована во всех основных браузерах.

Вы можете создать свой URL-адрес в интерфейсе и загрузить его следующим образом:

 var url = 'http://example.com/order-results/' + id + '/export-pdf?' + '..params..' 

 window.open(url, '_blank');

Надеюсь это поможет!

Ответ 4

У меня был аналогичный issues-, я закончил создание ссылки и загрузку оттуда.

Я поставил более подробную информацию о том, как в ответе на другой вопрос stackoverflow.

Ответ 5

Я попробовал некоторые из предложенных выше подходов, но в моем случае браузер отправлял мне предупреждение о блокировке всплывающих окон. Код, описанный ниже, работал для меня:

axios.get(url, {responseType: 'arraybuffer'})
   .then(function (response) {
     var headers = response.headers();
     var blob = new Blob([response.data],{type:headers['content-type']});
     var link = document.createElement('a');
     link.href = window.URL.createObjectURL(blob);
     link.download = "Your_file_name";
     link.click();
});