Processing dynamically generated forms

Document created by Dave Murphy Employee on Jul 20, 2017Last modified by Dave Murphy Employee on Jul 20, 2017
Version 2Show Document
  • View in full screen mode

Recently, i ran into a page which contained a form that was dynamically generated. The complete contents of this form needed to be sent as a POST body in the subsequent request. Because the input names of this form were dynamically generated and random, i could not simply create a property for each value and use that in the post. Here are instructions for dealing with this type of scenario.

 

Take this form example:

<INPUT TYPE=HIDDEN NAME="cmds" VALUE="EX017A7C1D95JGDC$C0$85$D9$B2$C0$85$D9$B201000JGDC$C0$85$D9$B2$C0$85$D9$B2$CAJJ0$12000$32!2$30$31$33$31$33$39$36$32!2$30$37$32$37$36$38$34$FF1!A0!C$FF220000!4$FF!S0100"> 
<INPUT TYPE=HIDDEN NAME="hidi1" VALUE="4803018">
<INPUT TYPE=HIDDEN NAME="hari1" VALUE="200131396200727684">
<INPUT TYPE=HIDDEN NAME="fsam" VALUE="1"> <INPUT TYPE=HIDDEN NAME="cmnd" VALUE="">
<INPUT TYPE=HIDDEN NAME="piid" VALUE="e3bef726-48b3-442c-8ea3-705c6a62df99-0">
<INPUT TYPE=HIDDEN NAME="isel" VALUE="">
<INPUT TYPE=HIDDEN NAME="qscr" VALUE="cmps">

 

As you can see, all of these form names are randomly generated, so we need to extract not just the value, but also the name of the inputs, and construct them back into a valid post body to include in the next request.

 

First, extract the names of all hidden inputs, using the following XPath in a custom property. Choose the option to store "All Values", and call the property "inputNames":

//*[local-name()='INPUT' and @type='HIDDEN']/@name

 

Now that you have all the dynamic names, you can use the following script to iterate through those names, retrieve their values, and concatinate them together into a valid HTML request body.

var msg = $context.currentItem.previousItem; 
var inputNames = $prop.value("clip","inputNames"); // Array from Xpath: //*[local-name()='INPUT' and @type='HIDDEN']/@name
var pairArray = [];
var name, value; 

for(index in inputNames) {    
   name = inputNames[index];    
   var value = msg.getResponse(msg.RESPONSE_TEXT_AS_HTML, "//*[local-name()='INPUT' and @name='"+name+"']/@value");    
   $context.result.postMessage($context.result.LEVEL_INFO, "Value for " + name + ": " + value);    
   pairArray.push(escape(name)+"="+escape(value));


$prop.set("clip","dynamicRequestBody",pairArray.join("&"));
msg.clearResponse();

 

This script should be placed in your timeline immediately after the message which returned the dynamic form. It will save its output into a property called "dynamicRequestBody", which can then be used to post this form back to the server with all name/value pairs accounted for.

Attachments

    Outcomes