Front end to call server side REST request (PDFreactor)


#1

Hi everyone,

The scenario I have is:
I am trying to integrate a web service called PDFreactor, which takes an amount of HTML and converts it to a PDF.

  • I want a button on the front end that when clicked:
  • The server POSTS the html on the current page to the PDFreactor server endpoint via a REST service
  • Then the server sends the PDF to the client

I’m not sure what is the best way to approach this. I had a look at REST assets but i’m not sure how the REST asset would be able to get document.documentElement.outerHTML. If I pass in a hardcoded URL to the REST body, the web service doesn’t get access to every element in the DOM because some elements are generated after the page loads.

I am very green, so any advice would be greatly appreciated.
Kind regards,
Tom


(Bart Banda) #2

Could you write some JS that when a button is clicked, the JS grabs all the HTML of the current page and sends that as an AJAX post request to your REST asset endpoint which then just forwards that POST data to the PDFreactor API?


#3

Hi Bart, thanks for the reply.

Perhaps I am misunderstanding how the squiz REST resource assets work. I thought that those assets just made a HTTP request based on the data you put into their settings.

Is there an example of how you can AJAX data to a REST resource asset, I can have a look at? Is this done with the JavaScript API asset?


(Byrne) #4

Hey tplant,

When you access a REST asset in Matrix via its URL the REST asset will then go ahead and make the REST call for you.

when accessing any asset in Matrix you can use the:
%globals_get_%
%globals_post_%
to fetch data posted TO the rest asset and forward that in your matrix REST call.

So the Process is:
client side JS POST -> Matrix REST -> PDF Service -> Matrix REST (success/fail) -> responds to AJAX client side request


Client side JS: collect the HTML and format
Client side JS: create AJAX request with HTML as post body content and post to the Matrix REST asset URL.

function reqListener () {
  if(this.status === 200){
    console.log(this.response);
  }
}

var url = 'https://matrix.squiz/my-rest-asset';
var formData = new FormData();

formData.append('html', '<html>BLAH</html>');

var xhr = new XMLHttpRequest();
xhr.addEventListener("load", reqListener);
xhr.open("POST", url);
xhr.send(formData);

Matrix: receive the posted AJAX data using the globals key works and add to the post body , forward the request to your PDF service

request type: POST
URL: PDF service
post body: %globals_post_html%

This is pretty rough so you’ll need to test and debug but this is the basic flow.


#5

Thanks for the reply Andrew,

This is soooo close to working. The problem now, seems to be some kind of encoding issue.

If on the content container side I were to do something like:

    var formData = new FormData();
    
    formData.append('pdf-reactor-html', '<HTML>Hi</HTML>');  
    
    var xhttp = new XMLHttpRequest();
    xhttp.open('POST', '**URL of the Rest resource asset**', true);

    xhttp.send(formData);

The data gets sent to the REST resource asset, then the asset posts the following request body to the PDF reactor web service:

{
“document”: “%globals_post_pdf-reactor-html%”
}

But I get the response:
“Relative URLs or file system paths as input documents cannot be converted (document path: “& lt;HTML& gt;Hi& lt;/HTML& gt;”)”
[Note: there aren’t spaces between the &s, but I had to put them in otherwise they would be turned into markup]

So the problem seems to be that when the formdata gets posted across, the < > symbols get encoded to &lt and &gt.

Any ideas on how to get around this?


(Byrne) #6

You can encode, escape or convert the HTML to blob.
If you are trying to post HTML you need to remember that quotes etc will break the JSON, check out your network tab to see whats being sent

I consider the error again.

and a quick look at the doco says to me that you should be posting a URL to an HTML doco not HTML.
https://www.pdfreactor.com/request-trial/#tab-id-1

You might want to go back and have a read of the doco see what is expected.


#7

Sending the URL is the ideal way to do it, but if you are having trouble because elements on the page are getting rendered with AJAX (which I am), then you can pass in HTML as a string.

The network tab seems to be showing that the data which is being passed is the same as the page source. IE: tags are rendered as < and > etc.

If I pass the data as a blob such as:

formData.append('pdf-reactor-html', new Blob([document.documentElement.outerHTML], {type: 'text/html'}));

or better yet, if I can just JSON.stringify the whole request body then:

formData.append('pdf-reactor-html', new Blob([jsonData], {type: 'application/json'}));

How can access the blob data at the REST asset end? Is there a keyword modifier for blobs?
I tried just putting %globals_post_pdf-reactor-html% in the REST asset body, when I posted the JSON blob, but that didn’t seem to work.

If I just cut and paste the JSON that was being sent in the network tab, then it does work >.<

Cheers


#8

I was able to get it working with XML.

  1. Button on front end calls POST request, posting the document.documentElement.outerHTML as formData.
  2. REST asset grabs the data from the formData and wraps it in a XML body, then posts it to the PDFreactor server
  3. Then the requsets return to the client as a arraybuffer, which is converted to a pdf and Bingo, page becomes pdf and gets downloaded!

Thanks for your help Andrew.
If anyone else is attempting this and needs more info, feel free to message me :slight_smile: