admin管理员组

文章数量:1332382

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 .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?

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./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?

Share asked Nov 30, 2011 at 23:13 juliojulio 6,75815 gold badges65 silver badges82 bronze badges 1
  • 1 I would stay with the query string format (URL encoded). You can also try BASE64... – CodeZombie Commented Nov 30, 2011 at 23:17
Add a ment  | 

5 Answers 5

Reset to default 1

Query string format is fine, if it's easy for you to parse them back.

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  :)

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/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.), 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);
        }
    });

})();

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.

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 remend 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.

本文标签: javascripthow to encode cookie dataStack Overflow