Getting Cookies
When using a Suitelet, we have access to all of a request’s headers, and can get to them via context.request.headers. Here’s a sample of what the headers look like:
{
"X-Akamai-SR-Hop": "1",
"true-client-ip": "83.74.96.100",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6.1 Safari/605.1.15",
"x-forwarded-port": "443",
"x-advpf-parse-category": "DEFAULT_ALLHTML",
"Accept-Encoding": "gzip",
"True-Client-IP": "83.74.96.100",
"via": "1.1 v1-akamaitech.net(ghost) (AkamaiGHost), 1.1 akamai.net(ghost) (AkamaiGHost)",
"x-forwarded-host": "9999999-sb3.extforms.netsuite.com:443, 9999999-sb3.extforms.netsuite.com",
"host": "9999999-sb3.extforms.netsuite.com",
"X-Advpf-Parse-Category": "DEFAULT_ALLHTML",
"ns-client-ip": "83.74.96.100",
"connection": "keep-alive",
"cache-control": "no-cache, max-age=0",
"X-Real-IP": "55.140.23.28",
"Cookie": "sessionID=20170094-2961ae54-de92-49ac-a0a8-93f13786fede; NS_ROUTING_VERSION=LAGGING; c7tXy98SOdcsRmaJORP2xg=AAABhHfmy1MPCnHzorzdLrEhYIuHIuNVNakHqWKIjIhEl5W8hlAI5A",
"NS-Client-IP": "83.74.96.100",
"Akamai-Origin-Hop": "2",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"cookie": "sessionID=20170094-2961ae54-de92-49ac-a0a8-93f13786fede; NS_ROUTING_VERSION=LAGGING; c7tXy98SOdcsRmaJORP2xg=AAABhHfmy1MPCnHzorzdLrEhYIuHIuNVNakHqWKIjIhEl5W8hlAI5A",
"x-forwarded-proto": "https",
"accept-language": "en-US,en;q=0.9",
"X-Forwarded-Proto": "https",
"X-Forwarded-Host": "9999999-sb3.extforms.netsuite.com:443, 9999999-sb3.extforms.netsuite.com",
"Akamai-GRN": "0.4f6adc17.1669841763.d8873b13, 0.378cd017.1669841763.4e34b9ba",
"Connection": "keep-alive",
"Host": "9999999-sb3.extforms.netsuite.com",
"Pragma": "no-cache",
"x-forwarded-for": "83.74.96.100, 23.220.106.79, 55.140.23.28, 10.136.0.13",
"X-Forwarded-Port": "443",
"akamai-origin-hop": "2",
"pragma": "no-cache",
"Via": "1.1 v1-akamaitech.net(ghost) (AkamaiGHost), 1.1 akamai.net(ghost) (AkamaiGHost)",
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"x-real-ip": "55.140.23.28",
"x-akamai-sr-hop": "1",
"X-Akamai-CONFIG-LOG-DETAIL": "true",
"x-akamai-config-log-detail": "true",
"x-forwarded-server": "forms.na7.netsuite.com",
"Cache-Control": "no-cache, max-age=0",
"X-Forwarded-For": "83.74.96.100, 23.220.106.79, 55.140.23.28, 10.136.0.13",
"Accept-Language": "en-US,en;q=0.9",
"X-Forwarded-Server": "forms.na7.netsuite.com",
"accept-encoding": "gzip",
"user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.2.35 (KHTML, like Gecko) Version/15.16.1 Safari/605.2.35",
"akamai-grn": "0.4f6adc17.1669841763.d8873b13, 0.327cd017.1669841763.4e34b9ba"
}
Each header is listed twice, once with header name in lower case, and a second time in intercaps. I usually refer to the lower case versions, but I don’t think it matters all that much.
Cookies are available via the “cookie” header. It looks like this:
"cookie": "sessionID=20170094-2961ae54-de92-49ac-a0a8-93f13786fede; NS_ROUTING_VERSION=LAGGING; c7tXy98SOdcsRmaJORP2xg=AAABhHfmy1MPCnHzorzdLrEhYIuHIuNVNakHqWKIjIhEl5W8hlAI5A"
So we can reference it using context.request.headers[‘cookie’]. That’s easy enough. But that returns the entire cookie string value. To parse it, I wrote this function, which takes the script context, gets the cookie header, parses it, and returns it as an object.
function cookiesGet( context ) {
var cookies = {}
var cookiesOriginal = context.request.headers['cookie'];
if ( cookiesOriginal == null ) {
return cookies;
}
cookiesOriginal = cookiesOriginal.split("; ");
for ( var i = 0; i < cookiesOriginal.length; i++ ){
var thisCookie = cookiesOriginal[i];
thisCookie = thisCookie.split("=");
cookies[thisCookie[0]] = thisCookie[1];
}
return cookies;
}
The result will look something like this:
{
"sessionID": "20170094-2961ae54-de92-49ac-a0a8-93f13786fede",
"NS_ROUTING_VERSION": "LAGGING",
"c7tXy98SOdcsRmaJORP2xg": "AAABhHfmy1MPCnHzorzdLrEhYIuHIuNVNakHqWKIjIhEl5W8hlAI5A"
}
Setting Cookies
To set cookies in a Suitelet, we can use the context.response.setHeader method. For example, to drop a cookie with name-value pair “a=1” you would use something like this:
context.response.setHeader( { name: 'Set-Cookie', value: 'a=1; path=/' } );
Dropping multiple name-value pairs can be tricky. For example, to set a second name-value pair (“b=2”) you might try this…
context.response.setHeader( { name: 'Set-Cookie', value: 'a=1; b=2; path=/' } );
But the resulting cookie will only include the first name-value pair, and ignore the second.
Calling the setHeader method twice, like this…
context.response.setHeader( { name: 'Set-Cookie', value: 'a=1; path=/' } );
context.response.setHeader( { name: 'Set-Cookie', value: 'b=2; path=/' } );
will result in a cookie that includes only the second name-value pair.
One method that I’ve found to solve this issue is to put the values in an object, JSON-encode the object, and then URL-encode the JSON string. For example…
let values = {a: 1, b: 2}
values = JSON.stringify(values);
values = encodeURIComponent(values);
context.response.setHeader( { name: 'Set-Cookie', value: `values=${values}; path=/` } );
You would then read the cookie, and decode it. For example…
let cookies = cookiesGet( context ); let values = cookies.values; values = decodeURIComponent(values); values = JSON.parse( values );