Continuing my exceedingly slow JavaScript learning, I was doing an exercise on setting and retrieving cookies, only to discover that the chosen methods of preparing the cookie string have been depreciated and only now work in certain browsers (IE11, FF, Edge), and don’t in others (Chrome, Opera, Brave). The methods being escape()
and unescape()
Reading though MDN, it offers encodeURI(), and encodeURIComponent() as alternatives, but those seem targeted at URL construction rather than cookies. Are they also an appropriate way of handling spaces in cookie text strings too, or is there an alternative?
Why do you need encode and decode when storing in cookies in the first place?
I’ve always used functions similiar to this:
http://www.quirksmode.org/js/cookies.html
The reason given in the tutorial I was following was that you can’t store space in the cookie string, so you run it through escape()
first to insert %20
in its place. The code I have is as follows, which works in only some browsers as mentioned.
##HTML:
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Using Cookies</title>
<link type="text/css" rel="stylesheet" href="../css/style.css">
<script type="text/javascript" src="cookie.js"> </script>
</head>
<body>
<div id="main">
<div id="panel">JavaScript is not enabled/available and this may degrade the viewing experience presented on this webpage</div>
</div>
</body>
</html>
#JavaScript
function init()
{
'use strict';
var panel = document.getElementById('panel');
//Set a cookie
var user = escape( 'Mike McGrath,000456' );
var expiry = new Date();
expiry.setTime( expiry.getTime() + ( 7*24*60*60*1000 ) );
document.cookie = 'myData=' + user + ';' + 'expires=' + expiry.toGMTString() + ';';
// Get a cookie
if( document.cookie )
{
var cookieString = unescape( document.cookie );
var list = cookieString.split( '=' );
if( list[0] === 'myData' )
{
var data = list[1].split( ',' );
var userName = data[0];
var userAcct = data[1];
}
}
//Output cookie contents to <div id='panel'>
panel.innerHTML = 'Cookie String: ' + cookieString;
panel.innerHTML += '<br>Split List: ' + list;
panel.innerHTML += '<br>User Name: ' + userName;
panel.innerHTML += '<br>User Account: ' + userAcct;
}
document.addEventListener('DOMContentLoaded', init, false);
When using the cookies.set() interface, you don’t need to worry about escaping any more.
1 Like
Sure you can
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<script type="text/javascript">
function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function eraseCookie(name) {
createCookie(name,"",-1);
}
createCookie('TEST',"This value has spacees", 1)
console.log(readCookie('TEST'))
</script>
</body>
</html>
About whitespace… it appears that whitespace, commas, semicolons, and a few other characters are indeed technically disallowed in cookie values. That restriction is mentioned in the MDN page and confirmed in the cookie RFC. But, we all know that browsers can be lenient, and as markbrown’s example shows, browsers won’t throw a big fuss about whitespace.
About cookie.set… I had never seen that before and it looked interesting. I tried it real quick but couldn’t get it to work. I googled a little more and it sounds like this API is specifically for browser add-ons.
@chrisofarabia Ultimately the answer to your question is yes, encode/decodeURIComponent is an appropriate way of handling spaces and other special characters in cookie value strings. In fact the MDN page I liked to two paragraphs up explicitly recommends that approach.
The cookie value string can use encodeURIComponent() to ensure that the string does not contain any commas, semicolons, or whitespace (which are disallowed in cookie values).
1 Like
I did a very quick rework of my original code using encodeURIComponent() to replace escape(), and decodeURIComponent() to replace unescape(). That at least stopped jshint complaining.
Interestingly, it didn’t improve the response from Chrome, which still plays out the values as undefined
within the webpage, and when running document.cookie;
in the console, gives the result ""
. As before, IE11 runs things just fine, and I can see white space being replaced by %20
.
I need to dig into @markbrown4’s code still. It’s been a busy day.
Well those are the UTF8 equivalents of the deprecated ASCII-only escape and unescape.
That’s not a bad read. Rather more digestible than the ietf.org paper that’s for sure.
It looks like the the reason Chrome, Brave and Opera weren’t playing, was because the files weren’t being provided from a server. I dropped them onto the Linux box and voila; working as expected. My guess is there’s a security block built in somewhere that IE, FF and Edge don’t have.
Thanks for all the useful links and pointers.
This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.