Creating PDF from request response doesn't work with axios but works in native xhr

20,137

Solution 1

The following works for me:

axios.post("http://localhost:8080/reports/my-report/",
        data,
        {
            responseType: 'arraybuffer',
            headers: {
                'Content-Type': 'application/json',
                'Accept': 'application/pdf'
            }
        })
        .then((response) => {
            const url = window.URL.createObjectURL(new Blob([response.data]));
            const link = document.createElement('a');
            link.href = url;
            link.setAttribute('download', 'file.pdf'); //or any other extension
            document.body.appendChild(link);
            link.click();
        })
        .catch((error) => console.log(error));

Let me know if this helps.

Cheers!

Solution 2

For whatever reason the pdf is downloading but any content passed is not appearing resulting in a blank pdf.

I found this code snippet that is similar but results in a pdf with content.

 axios({
                url: '/pdf',
                method: 'GET',
                responseType: 'blob', // important
            }).then((response) => {
                const url = window.URL.createObjectURL(new Blob([response.data]));
                const link = document.createElement('a');
                link.href = url;
                link.setAttribute('download', 'file.pdf');
                document.body.appendChild(link);
                link.click();
            });

there was some feedback stating that it didnt work on IE 11, I have not tested it but a solution was posted using FileSaver.js

axios({
            url: '/pdf',
            method: 'GET',
            responseType: 'blob', // important
        }).then((response) => {
            FileSaver.saveAs(new Blob([response.data]));
        });
Share:
20,137

Related videos on Youtube

Victor
Author by

Victor

[email protected] for contact

Updated on July 09, 2022

Comments

  • Victor
    Victor almost 2 years

    In order to force download PDF from server I tried to use axios and native xhr object. The reason is that I have to send post request, because I pass too much data to server, so the option with simple link (like site.ru/download-pdf won't work for me).

    Even though I finally managed to do this with Xhr, I still don't have a clue why axios way doesn't work.

    Here is how I do this with xhr and it works for me:

        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()
          }
        };
    
        xhr.send("data=" + data);
    

    Here is "axios-way" and I actually get PDF with correct number of pages, but they are all empty:

        axios.post(`order-results/${id}/export-pdf`, {
          data,
          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 = 'Results.pdf'
          link.click()
        })
    

    Axios is already configured to send Authorization token. I put Application/x-www-form-urlencoded in xhr because otherwise I couldn't get data in server side.

    Even though xhr works, I'd prefer to use axios since I use it everywhere and I'm just curios what I'm doing wrong. I tried different solutions, and only native xhr did the job.

  • Zero Zhang
    Zero Zhang almost 6 years
    It works. I miss responseType: 'arraybuffer' in request config.
  • Old Man Walter
    Old Man Walter over 4 years
    this works great, as far as it goes. Now, how to use the filename that is coming from the server? content-disposition: attachment; filename="My Test - Doc Title.pdf"
  • Edeph
    Edeph over 3 years
    What does the responseType: 'arraybuffer' do that it makes it so critical ?
  • Ali Rehman
    Ali Rehman over 3 years
    It really helped. Thanks