59 votes

Forcer le téléchargement d'une requête GET à l'aide d'axios

Je suis en utilisant vuejs 2 + axios. J'ai besoin d'envoyer une requête get, passer des paramètres au serveur, et d'obtenir un fichier PDF en tant que réponse. Le serveur utilise Laravel.

Donc

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

fait succès de la demande, mais il ne démarre pas forcer le téléchargement, même si le serveur renvoie corriger les en-têtes.

Je pense que c'est une situation typique quand vous en avez besoin, par exemple, la forme d'un rapport au format PDF et passer quelques filtres sur le serveur. Alors, comment pourrait-il être réalisé?

Mise à jour

Donc en fait j'ai trouvé une solution. Cependant, la même approche ne fonctionne pas avec axios, je ne sais pas pourquoi, c'est pourquoi j'ai utilisé raw objet XHR. Donc la solution est de créer un objet blob et l'utilisateur createUrlObject fonction. Exemple d'échantillon:

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

Important: vous devriez avoir de la matrice de la mémoire tampon de réponse de type

Cependant, le code écrit dans axios retourne PDF qui est vide:

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

81voto

Roshimon Points 780

Vous obtenez vide PDF 'cause aucune donnée n'est transmise au serveur. Vous pouvez essayer de passer des données à l'aide des données de l'objet comme ceci

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

Par la façon dont je dois vous remercie beaucoup pour me montrer l'astuce pour télécharger le pdf de réponse. Merci ya :)

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

La façon dont j'ai utilisé est,

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

15voto

gtamborero Points 704

Essayez ceci: cela fonctionne parfaitement pour moi avec la compatibilité pour Internet Explorer 11 (createObjectURL ne fonctionne pas sur 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

5voto

Deepak Points 983

Je ne pense pas que ce soit possible de le faire dans axios ou même AJAX. Le fichier sera conservé en mémoire, c'est-à-dire que vous ne pouvez pas enregistrer le fichier sur le disque. En effet, JavaScript ne peut pas interagir avec le disque. Ce serait un grave problème de sécurité et il est bloqué dans tous les principaux navigateurs.

Vous pouvez créer votre URL en front-end et la télécharger de la manière suivante:

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

 window.open(url, '_blank');
 

J'espère que cela t'aides!

4voto

Bruno Soares Points 71

J'ai essayé certaines des approches suggérées ci-dessus mais dans mon cas, le navigateur m'envoyait l'avertissement de blocage de popup. Le code décrit ci-dessous a fonctionné pour moi:

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

-1voto

Anthony Points 162

J'ai eu des problèmes similaires - j'ai fini par créer un lien et télécharger à partir de là.

J'ai mis plus de détails sur la façon dont dans la réponse à une autre question stackoverflow.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X