reverse engineering downloading a profile page as HTML

Viewed 59

This is a multi-part process. There's a button on a page that lets me download a page as a pdf that I'm trying to build into a Chrome extension:

1.) button is clicked

2.) api is hit, checking to see if the page is ready to be downloaded, it looks something like this

{"error":false,"printError":false,"msg":"Not Ready","ready":false,"id":1108908001,"link":"streamPdf/1108908001"}
{"error":false,"printError":false,"msg":"Ready","ready":true,"id":1108908001,"link":"streamPdf/110890800"}

3.) Once it reads as ready, the next request is made

fetch("https://www.website.com/cap/people/streamPdf/1108908001"});

This returns the HTML value of the page

4.) convert HTML value to base64

5.) then the browser fetches the pdf

fetch("data:application/pdf;base64,"+base64);

6.) PDF downloads

However, when I copy fetch for Step #5 and paste it into the browser, it doesn't trigger the download.

I would have expected that to trigger a file. Is there something that I'm missing to trigger creating a PDF?

The code that I have so far:

var canID = "someNUM"
fetch("https://www.website.com/cap/people/printStateAjax?id="+canID)
.then(resp=>resp.json())
.then(data=>{
    if(data.msg == "Ready") {
        console.log('ready')
        fetch("https://www.website.com/cap/people/streamPdf/"+canID)
        .then(resp => {return resp.text()})
        .then(data => {
            var base64 = btoa(unescape(encodeURIComponent(data)))
            console.log('1')
            return base64
        })
        .then(base64 => {
            fetch("data:application/pdf;base64,"+base64)
            .then(resp => {return resp.blob()})
            .then(blob => {
                const url = window.URL.createObjectURL(blob);
                const a = document.createElement('a');
                a.style.display = 'none';
                a.href = url;
                // the filename you want
                a.download = 'test_pdf';
                document.body.appendChild(a);
                a.click();
                window.URL.revokeObjectURL(url)
            })
        })
    }
})

This downloads a PDF, but the PDF is empty. What am I doing wrong?

1 Answers

I wonder if something simpler might work - like this...

var canID = "someNUM"
fetch("https://www.website.com/cap/people/printStateAjax?id="+canID)
  .then(resp=>resp.json())
  .then(data=>{
    if(data.msg == "Ready") {
      console.log('ready')
      fetch("https://www.website.com/cap/people/streamPdf/"+canID,
            {
              headers: {
                "Content-Type":"application/pdf"
              }
            }
           )
        .then(resp => resp.blob())
        .then(blob => {
          const url = window.URL.createObjectURL(blob);
          const a = document.createElement('a');
          a.href = url;
          // the filename you want
          a.download = 'test_pdf.pdf';
          a.click();
          window.URL.revokeObjectURL(url)
        })
    }
  });

This just grabs the blob and hands it to the link.

Also I think you don't actually have to add that a tag to the DOM to make it work.

I did not try this in a browser so there may be some minor syntax errors but conceptually I think it's close.

Related