0
votes

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

1
You can check these answers. You can avoid downloading in js, and just construct the link <a href="path_to_file" download="proposed_file_name">Download</a>, where you can use the :href="url" in vue. I think even window.location = <pdf-url-here> would work and it should the downloadljubadr
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
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 backendljubadr
Here is the example how to set php headers stackoverflow.com/a/20080402/3226121ljubadr

1 Answers

2
votes

You must pass an array to blob constructor

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

Docs