Reputation: 6748
I'm setting a cookie with some query string values for a page I've built, so that when you revisit the page you will have option set for you.
So if the URL is http://mysite.com/index.php?setting1=blue&orientation=horizontal&background=paper
the cookie will store the setting1=blue
, orientation=horizontal
, and background=paper
values to be read back on the next visit.
It seems like most people advise json encoding these values prior to storing in the cookie. However, I'm getting way bigger cookie sizes (like 4-5x bigger!) when json encoding vs. just saving these values in a standard query string format and parsing them later.
Any best practice for this situation?
Upvotes: 3
Views: 9215
Reputation: 5701
If you want to convert a query string to an object take a look at
myQueryString.parseQueryString() // returns object of key value pairs
Requires mooTools More Strings: http://mootools.net/docs/more/Types/String.QueryString
However i like the idea of Base64 more! See below
Credit goes to Ryan Florence for this but this is what i use:
var cookieData = DATATOENCODE.toBase64() // base64 encodes the data
cookieData.decodeBase64() // to decode it
The magic:
/*
---
script: Base64.js
description: String methods for encoding and decoding Base64 data
license: MIT-style license.
authors: Ryan Florence (http://ryanflorence.com), webtoolkit.info
requires:
- core:1.2.4: [String]
provides: [String.toBase64, String.decodeBase64]
...
*/
(function(){
// Base64 string methods taken from http://www.webtoolkit.info/
var Base64 = {
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encode : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
};
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
};
return output;
},
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
};
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
};
};
output = Base64._utf8_decode(output);
return output;
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
};
};
return utftext;
},
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
};
};
return string;
}
};
String.implement({
toBase64: function(){
return Base64.encode(this);
},
decodeBase64: function(){
return Base64.decode(this);
}
});
})();
Upvotes: 1
Reputation: 4026
Well, if you're using MooTools, simply use Hash.Cookie
, it's nifty and will get you rid of your headaches by abstracting this stupid cookie storage stuff :)
Upvotes: 1
Reputation: 29985
If they're that much bigger, you're probably doing something wrong. setting1=blue
can be represented as {"setting1":"blue"}
- adding orientation=horizontal
gives {"setting1":"blue","orientation":"horizontal"}
- it definitely takes more space in the cookie but not that much.
Also, I'd personally recommend against using JSON. It's too easy for an attacker from a different website to set a cookie on your domain which could then get executed as JSON. The NVP "encoding" is more effective if you're only doing key/value storage.
Upvotes: 0
Reputation: 21476
I don't know if there is a best practice for this, but I would advise using the query string format since it's smaller.
Cookies are transferred with every page request. Less data transferred is almost always better.
Upvotes: 0
Reputation: 490607
Query string format is fine, if it's easy for you to parse them back.
Upvotes: 1