最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Getting pdf file from api response - Stack Overflow

programmeradmin6浏览0评论

I am calling an api and getting pdf in return.

fetch(`api` + guid, {
   method: "GET",
   headers: {
    "Accept": "application/octet-stream",
    "Authorization": "Bearer " + token,
   },
   responseType: 'arraybuffer',
})
.then((res) => res.text())
.then((data) => {
    fs.writeFileSync('file.pdf', data);
});

I get the pdf file but the issue is the pdf file is always empty. But when I accept response as json, it works fine.

I found similar problems like this but none of the solution worked for me yet.

It would be great if someone can point out the issue.

I am calling an api and getting pdf in return.

fetch(`api` + guid, {
   method: "GET",
   headers: {
    "Accept": "application/octet-stream",
    "Authorization": "Bearer " + token,
   },
   responseType: 'arraybuffer',
})
.then((res) => res.text())
.then((data) => {
    fs.writeFileSync('file.pdf', data);
});

I get the pdf file but the issue is the pdf file is always empty. But when I accept response as json, it works fine.

I found similar problems like this but none of the solution worked for me yet.

It would be great if someone can point out the issue.

Share Improve this question edited Apr 10, 2022 at 21:51 Yogesh Bhattarai asked Nov 16, 2020 at 13:34 Yogesh BhattaraiYogesh Bhattarai 3521 gold badge2 silver badges12 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 14

I found the issue. As I am using fetch not Axios. We cannot pass responseType as Fetch's option.

fetch(`api` + guid, {
   method: "GET",
   headers: {
    "Accept": "application/octet-stream",
    "Authorization": "Bearer " + token,
   },
   // responseType: 'arraybuffer' //#1 remove this,
})

Instead the response in itself can be passed as arraybuffer as below.

.then((res) => res.arraybuffer())

instead of

.then((res) => res.text())

Now instead of directly using the response to write our pdf file. We can change the data to base64 string and decode it back again to create our pdf file. I used base64ToPdf npm package to handle that.

.then(data => {
  var base64Str = Buffer.from(data).toString('base64');
  base64.base64Decode(base64Str, "file.pdf");
})

I hope this help others. :)

    Change res.arraybuffer() to  res.arrayBuffer()

Below is the working code with webdriverio-

  var headers = {
            Authorization: "Bearer " + accessToken,
            Accept: 'application/pdf'
        }
       
           fetch(
                apiurl,
                {
                    headers: {
                        Accept: "application/octet-stream",
                        Authorization: "Bearer " + accessToken
                    },
                },
            )
                .then((res) => {
                    if (!res.ok) {
                        return res.status.toString()
                    }
                    return res.arrayBuffer()
                })
                .then((data) => {
                    var base64Str = Buffer.from(data).toString('base64');
                    base64.base64Decode(base64Str, filename);
                })
                .catch(
                    (err) => {
                        return err.Message;
                    })

    

Here's example which works for me:

async createPdf(context, data) {
    let url = new URL(baseURL + '/invoice/createPdf');
    url.search = new URLSearchParams({
        id: data
    })

    await fetch(url, {
        method: 'GET',
        headers: {
            'Authorization': "Bearer " + localStorage.getItem("jwt"),
            'Accept': 'application/octet-stream'
        },
    }).then((res) => res.arrayBuffer())
        .then(data => {
            var base64Str = Buffer.from(data).toString('base64');

            var binaryString = window.atob(base64Str);
            var binaryLen = binaryString.length;
            var bytes = new Uint8Array(binaryLen);
            for (var i = 0; i < binaryLen; i++) {
                var ascii = binaryString.charCodeAt(i);
                bytes[i] = ascii;
            }
            var arrBuffer = bytes;

            var newBlob = new Blob([arrBuffer], { type: "application/pdf" });

            if (window.navigator && window.navigator.msSaveOrOpenBlob) {
                window.navigator.msSaveOrOpenBlob(newBlob);
                return;
            }

            data = window.URL.createObjectURL(newBlob);

            var link = document.createElement('a');
            document.body.appendChild(link);
            link.href = data;
            link.download = "Faktura.pdf";
            link.click();
            window.URL.revokeObjectURL(data);
            link.remove();
        })
}

In my case, the response is same as yours and I'm trying to convert it to a pdf file so that I can preview it on the UI.

For this, I need to fetch the URL already present in the response which is of type blob... to fetch the URL I did URL.createObjectURL(myblob)

const [url,seturl] = useState('');
response
  .then((resp) => resp.blob())
  .then((myBlob) => {
    seturl(URL.createObjectURL(myBlob)); //<-- use this for fetching url from your response
    console.log(myBlob);
  })
  .catch((err) => {
    console.log(err.message());
  });
发布评论

评论列表(0)

  1. 暂无评论