0

I have a REST API (POST method) which returns the content of a PDF. I tested using curl and I do can see and open the file on my computer:

curl http://localhost:8080/ponyapp/test/generate-pdf -H 'Content-Type: application/json' -d '[{"fieldA":"valueA", "fieldB":"valueB", ...}]' -i -o ~/Desktop/label.pdf

Now I have a vuejs/js application which needs to use this REST API and be able to save the file into the local computer. My approach (please correct me if I am wrong) is:

  1. call the API to get the response payload
  2. put the payload into a file
  3. download the file into the local computer by using HTML anchor element

For some reason, this is not working

This the response payload:

%PDF-1.4↵%����↵1 0 obj↵<<↵/CreationDate(D:20200301141435+13'00')↵/Title(CourierPost Label)↵/Creator(PDFsharp 1.50.4000-wpf (www.pdfsharp.com))↵/Producer(PDFsharp 1.50.4000-wpf (www.pdfsharp.com))↵>>↵endobj↵2 0 obj↵<<↵/Type/Catalo...

I have tried different variations of this code:

  axios
    .post(
      this.$store.state.baseUrl + "test/generate-pdf",
      [this.uberShipment],
      {
        responseType: "blob",
        headers: {
          Authorization: "Bearer " + this.getToken()
        }
      }
    )
    .then(response => {
      let filename = "label" + new Date().toISOString() + ".pdf";

      let data = new Blob(response.data, { type: 'application/pdf,' });

      let link = document.createElement("a");
      link.setAttribute("href", (window.webkitURL || window.URL).createObjectURL(data));
      link.setAttribute("download", filename);
      link.click();
    })
    .catch(error => {
      ...
    })

Which fails with the error below:

error = TypeError: Failed to construct 'Blob': The provided value cannot be converted to a sequence. at eval (webpack-internal:///./node_modules/cache-loader/dist/cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/vuetify-loader/lib/loader.js?!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/components/CreateShipmentAndNZPostDomesticLabel.vue?vue&type=script&lang=js&:604:20) _this

I would appreciate any advice of why this is not working (either in my approach or in the code)

thank you

masber
  • 2,875
  • 7
  • 29
  • 49
  • You can check [these answers](https://stackoverflow.com/questions/11620698/how-to-trigger-a-file-download-when-clicking-an-html-button-or-javascript). You can avoid downloading in js, and just construct the link `Download`, where you can use the `:href="url"` in vue. I think even `window.location = ` would work and it should the download – ljubadr Mar 01 '20 at 02:58
  • I may be misunderstanding your comment. The file does not exist. I need to make a REST call to the server (proxy) which will use the request payload to get get the content the pdf content from another server. Not sure whether I explained properly. – masber Mar 01 '20 at 03:08
  • 1
    You don't need ajax for this, just link the file or set window.location. Also, make sure to set correct headers for pdf on your backend – ljubadr Mar 01 '20 at 03:13
  • Here is the example how to set php headers https://stackoverflow.com/a/20080402/3226121 – ljubadr Mar 01 '20 at 03:14

1 Answers1

4

You must pass an array to blob constructor

let data = new Blob([response.data], { type: 'application/pdf,' });

Docs

Danny Matkovsky
  • 662
  • 4
  • 14