My problem at hand is that I need a variable that will keep track of all of my cookies so that I can split up the string in that variable into an array and then parse the string from there. I am wondering why the simple following code is not doing that for me?
var count = 0; //keeps track of how many times this page has been visited
var lastVisit = new Date(); //records the last visit date in UTC format (or extra-challenge: in a user-friendly format like "Tuesday 10/12/2013 at 9:34:50")
var exDate = new Date(lastVisit.getTime() + 30000);
var savedData = decodeURI(document.cookie); //contains cookie contents
document.cookie = encodeURI("count=" + count.toString() + "; expires=" + exDate.toUTCString());
What I need to happen is whenever I set a cookie for it to be added to the savedData variable, I cannot figure out why this is not happening. Thank you
My problem at hand is that I need a variable that will keep track of all of my cookies so that I can split up the string in that variable into an array and then parse the string from there. I am wondering why the simple following code is not doing that for me?
var count = 0; //keeps track of how many times this page has been visited
var lastVisit = new Date(); //records the last visit date in UTC format (or extra-challenge: in a user-friendly format like "Tuesday 10/12/2013 at 9:34:50")
var exDate = new Date(lastVisit.getTime() + 30000);
var savedData = decodeURI(document.cookie); //contains cookie contents
document.cookie = encodeURI("count=" + count.toString() + "; expires=" + exDate.toUTCString());
What I need to happen is whenever I set a cookie for it to be added to the savedData variable, I cannot figure out why this is not happening. Thank you
Share Improve this question asked Nov 13, 2013 at 21:39 justin henricksjustin henricks 4673 gold badges6 silver badges18 bronze badges 3 |2 Answers
Reset to default 12You're not supposed to encode 'expires='. It will turn into 'expires%3D', which is not what you want. In addition to that, it might be a bad idea to use 'encodeURI', because it does not encode ';' and ',' as required.
You can use encodeURIComponent for encoding the cookie value, but it would be technically correct to use escape() to encode the cookie value.
So...
document.cookie = "count=" + encodeURIComponent(count.toString()) + "; expires=" + exDate.toUTCString();
...should do what you want.
The cookie consists of several parts; we're mostly interested in the name, the value and the expiry date.
(End of official answer)
Let's clear up the confusion on encoding cookies
If ever in doubt, contact the RFC, do not just pick anything you find on the Web that seems to work.
The cookie-name is of type token, which means that only these values are allowed within it:
0x21-0x27, 0x2A-0x2B, 0x2D-0x2E, 0x30-0x39, 0x41-0x5A, 0x5E-0x7A and 0x7E.
In other words: The following values should be percent-encoded:
0x00-0x20, '(', ')', ',', '/', ':', ';', '<', '=', '>', '?', '@', '', '[', ']', '{', '}' and 0x7F-0xFF.
The cookie-value is of type cookie-octet, which means that only these values are allowed within it:
0x21, 0x23-0x2B, 0x2D-0x3A, 0x3C-0x5B, 0x5D-0x7E.
In other words: The following values should be percent-encoded:
0x00-0x20, 0x22, ',', ';', '' and 0x7F-0xFF.
Now, the expiry date is encoded using toUTCString(), as you're correctly doing.
The result looks something like this: Wed, 09 Jun 2021 10:18:14 GMT
-So it will contain a comma. BUT! You're not supposed to encode anything, except the cookie-name and cookie-value strings.
Note: W3Schools says that escape() was deprecated in JavaScript 1.5, but it is technically incorrect to use encodeURI() or encodeURIComponent() for cookies. It is technically correct to use escape() for cookies.
RFC 6265 section 5.4 clearly states:
NOTE: Despite its name, the cookie-string is actually a sequence of
octets, not a sequence of characters. To convert the cookie-string
(or components thereof) into a sequence of characters (e.g., for
presentation to the user), the user agent might wish to try using the
UTF-8 character encoding [RFC3629] to decode the octet sequence.
This decoding might fail, however, because not every sequence of octets is valid UTF-8.
As decodeURIComponent() is for unicode strings, and choke on byte values between 0x00 and 0xFF, they can not safely be used. On the other hand, unescape() is not for strings, but for 8-bit byte-sequences, aka. octets, but only if your byte-sequences do not contain unicode characters.
If your cookie value contains unicode characters, you should however, use encodeURIComponent()/decodeURIComponent(), but you should also catch any exceptions, because the server may not send you exactly what you want to receive.
Most browsers also support btoa
for encoding in Base64 and atob
for decoding Base64. All characters in Base64 are legal cookie-octets (when interpreted in ASCII or UTF-8). So you can (at the cost of additional storage space) store a Base64 encoding of your persistent value as the cookie value, encoding (and decoding) as you persist (and retrieve) the value.
savedData
contains the value ofdocument.cookie
not a reference to it. So whendocument.cookie
is altered, this will not affect thesavedData
. – levi Commented Nov 13, 2013 at 23:21savedData
in sync, you can create a helper functionsetCookie
which sets the cookie, and updates thesavedData
. – levi Commented Nov 13, 2013 at 23:22