it-swarm.com.de

Erzwinge den Download der GET-Anfrage mit Axios

Ich verwende vuejs 2 + axios . Ich muss eine Get-Anfrage senden, einige Parameter an den Server übergeben und als Antwort eine PDF erhalten. Server verwendet Laravel.

So

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

sendet eine erfolgreiche Anforderung, aber der Download wird nicht erzwungen, obwohl der Server korrekte Header zurückgibt.

Ich denke, dies ist eine typische Situation, wenn Sie beispielsweise einen PDF - Bericht erstellen und einige Filter an den Server übergeben müssen. Wie konnte es erreicht werden?

Update

Also habe ich tatsächlich eine Lösung gefunden. Der gleiche Ansatz funktionierte jedoch nicht mit Axios, ich weiß nicht warum, deshalb habe ich rohe XHR-Objekte verwendet. Die Lösung besteht also darin, ein Blob-Objekt und eine createUrlObject-Funktion des Benutzers zu erstellen. Beispielbeispiel:

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

Wichtig: Als Antworttyp sollten Sie Array-Puffer haben

Derselbe Code, der in axios geschrieben ist, gibt jedoch PDF zurück, was leer ist:

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

Sie werden leer PDF, da keine Daten an den Server übergeben werden. Sie können versuchen, Daten mit einem Datenobjekt wie diesem zu übergeben

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

Übrigens, ich muss mich bei Ihnen so sehr bedanken, dass Sie mir den Hinweis gezeigt haben, um das PDF aus der Antwort herunterzuladen. Danke dir :)

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

Die Art und Weise, in der ich verwendet habe, ist

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

42
Roshimon

Versuchen Sie Folgendes: Es funktioniert perfekt für mich mit der Kompatibilität für Internet Explorer 11 (createObjectURL funktioniert nicht mit 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

8
gtamborero

Ich glaube nicht, dass dies in Axios oder sogar AJAX möglich ist. Die Datei wird gespeichert, d. H. Sie können die Datei nicht auf der Festplatte speichern. Dies liegt daran, dass JavaScript nicht mit der Festplatte interagieren kann. Dies wäre ein ernstes Sicherheitsproblem und wird in allen gängigen Browsern blockiert. 

Sie können Ihre URL im Frontend erstellen und auf folgende Weise herunterladen:

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

 window.open(url, '_blank');

Hoffe das hilft!

3
Deepak

Ich habe einige der oben vorgeschlagenen Ansätze ausprobiert, aber in meinem Fall hat der Browser mir die Popup-Blockierungswarnung gesendet. Der unten beschriebene Code hat für mich funktioniert:

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();
});
0
Bruno Soares

Ich hatte ähnliche Probleme - am Ende habe ich einen Link erstellt und von dort heruntergeladen.

Ich füge weitere Einzelheiten dazu in der answer zu einer anderen stackoverflow-Frage hinzu.

0
Anthony