SFMC SSJS: How to use URL form encoded with Script.Util.HttpRequest
Content Type
The application/x-www-form-urlencoded
content type describes POST data that is sent in a single block in the HTTP message body. But how is the body formatted? It is basically a long URL encoded string with key-value tuples separated by an ampersand '&'
, with a '='
between the key and the value. Non-alphanumeric characters are percent encoded.
Example: key1=value1&key2=value2[&key3=value3&etc ...]
Converting our payload
In our POST request we need to indicate the ContentType we are sending, and therefore, if the server is expecting application/x-www-form-urlencoded
then we need to supply that. In order to do so, we need to write our own function to convert our payload object into the correct format for our POST request.
function toFormEncoded(obj) {
var newArr = [];
if (typeof(obj)=='object') {
for (var i in obj) {
var encodedKey = encodeURIComponent(i);
var encodedValue = encodeURIComponent(obj[i]);
newArr.push(encodedKey + "=" + encodedValue);
}
return newArr.join("&");
}
}
var payload = {
'userName' : 'test@gmail.com',
'password' : 'myPwd',
'grant_type' : 'password'
};
var res = performPostRequest(url, toFormEncoded(payload))
This will pass in our POST body data in the correct format, ready for Script.Util to execute the call.
function performPostRequest(endpoint, payload) {
var req = new Script.Util.HttpRequest(endpoint);
req.emptyContentHandling = 0;
req.continueOnError = true;
req.retries = 2;
req.setHeader("Cache-Control","no-cache");
req.contentType = "application/x-www-form-urlencoded";
req.encoding = "UTF-8";
req.method = "POST";
req.postData = payload; /* already form encoded string */
try {
var api = req.send();
if (api.statusCode == 200) {
var response = {
"statusCode" : api.statusCode,
"returnStatus" : api.returnStatus,
"headers" : api.headers,
"contentType" : api.contentType,
"encoding" : api.encoding,
"results" : Platform.Function.ParseJSON(String(api.content))
};
return response;
} else {
throw "Status: " + api.statusCode + " Error with Post function request. Throw Error: " + Platform.Function.ParseJSON(String(api.content));
};
} catch (error) {
Write("POST API function Caught an Error: " + Stringify(error));
};
};
Thus we can take
var payload = {
'userName': 'test@gmail.com',
'password': 'myPwd',
'grant_type': 'password'
};
and turn it into
userName=test@gmail.com&password=myPwd&grant_type=password
for use in our new Script.Util.HttpRequest()
POST request alongside contentType = "application/x-www-form-urlencoded"
BONUS
To convert urlformencoded back to a JavaScript key:value object:
function getFormPostData() {
var postData = Platform.Function.ParseJSON(Platform.Request.GetPostData('utf-8'));
if (postData && typeof(postData) != 'object' && postData.indexOf('&') !== -1) {
var postObject = {};
var postArray = postData.split('&')
for (var i=0; i<postArray.length; i++) {
var key = postArray[i].split('=')[0];
var value = postArray[i].split('=')[1];
postObject[key] = value;
}
postData = postObject;
}
return postData;
};