Paksa unduh permintaan GET menggunakan axios

Saya menggunakan vuejs 2 + axios. Saya perlu mengirim permintaan get, meneruskan beberapa params ke server, dan mendapatkan PDF sebagai respons. Server menggunakan Laravel.

Jadi

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

membuat permintaan yang sukses tetapi tidak memulai pengunduhan paksa, meskipun server mengembalikan header yang benar.

Saya pikir ini adalah situasi umum ketika Anda perlu, katakanlah, membentuk laporan PDF dan meneruskan beberapa filter ke server. Jadi bagaimana itu bisa dilakukan?

Update

Jadi sebenarnya saya menemukan solusi. Namun pendekatan yang sama tidak berhasil dengan axios, tidak tahu mengapa, itu sebabnya saya menggunakan objek XHR mentah. Jadi solusinya adalah membuat objek blob dan menggunakan fungsi createUrlObject. Contoh contoh:

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()
  }
}

Penting: Anda harus memiliki buffer array sebagai tipe respon

Namun, kode yang sama yang ditulis dalam axios mengembalikan PDF yang kosong:

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
})
Larutan

Anda mendapatkan PDF kosong karena tidak ada data yang dioper ke server. Anda dapat mencoba mengoper data menggunakan objek data seperti ini

  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
    })

Ngomong-ngomong, saya harus berterima kasih banyak karena telah menunjukkan kepada saya petunjuk untuk mengunduh pdf dari tanggapan. Terima kasih ya :)

                var dates = {
                    fromDate: 20/5/2017,
                    toDate: 25/5/2017
                }

Cara yang saya gunakan adalah,

axios({
  method: 'post',
  url: '/reports/interval-dates',
  responseType: 'arraybuffer',
  data: dates
}).then(function(response) {
  let blob = new Blob([response.data], { type: 'application/pdf' })
  let link = document.createElement('a')
  link.href = window.URL.createObjectURL(blob)
  link.download = 'Report.pdf'
  link.click()
})
Komentar (2)

Saya rasa tidak mungkin melakukan ini di axios atau bahkan AJAX. File akan disimpan dalam memori, yaitu Anda tidak dapat menyimpan file ke disk. Ini karena JavaScript tidak dapat berinteraksi dengan disk. Itu akan menjadi masalah keamanan yang serius dan itu diblokir di semua browser utama.

Anda dapat membuat URL Anda di front-end dan mengunduhnya dengan cara berikut:

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

 window.open(url, '_blank');

Semoga ini membantu!

Komentar (2)

Saya mengalami masalah yang sama - saya akhirnya membuat tautan dan mengunduh dari sana.

Saya menaruh lebih banyak rincian tentang bagaimana caranya di jawaban pada pertanyaan stackoverflow lain.

Komentar (0)