patternjavascriptMinor
Lightweight Cookiemanager
Viewed 0 times
lightweightcookiemanagerstackoverflow
Problem
I've been working on a lightweight cookiemanager and version 1 has been completed and works perfectly as intended. I would love to get a review to see where we can improve it.
Where should I throw logical errors? For now I only log.
Its usage is as follows:
Getting cookies can be done by calling
Setting cookies can be done by calling
Removing cookies can be done by calling
Testing a cookie against a certain value
Where should I throw logical errors? For now I only log.
Its usage is as follows:
Getting cookies can be done by calling
Cookiemanger.get(). You can supply a name argument to get a specific cookie, if no name is supplied it will return all cookies currently in the document. An additional flag can be set as a second argument whether to use strict matching on the cookies name.Cookiemanager.get(); // returns all cookies currently defined in the document as a name/value object.
Cookiemanager.get('your_cookie_name'); // returns cookie(s) as a name/value object, using loose matching. so 'your_cookie_name_123' will get returned also.
Cookiemanager.get('your_cookie_name', true); // Same as above only now it will do strict name matching.Setting cookies can be done by calling
Cookiemanger.set(). It requires a settings object with at least a name key/value supplied.// Simple setting
Cookiemanger.set({
name : 'your_cookie_name',
value : 'your value'
});
// Extended setting
Cookiemanger.set({
name : 'your_cookie_name',
value : 'your value',
expires : 'a expiry date in as a UTC string'
path : '/',
domain : document.location.host,
secure : false
});Removing cookies can be done by calling
Cookiemager.remove(). It accepts 3 arguments: name, domain and path as a string. domain and path are optional. If none are supplied, it will remove all cookies from the domain including all sub paths.// Removes the cookie at the current domain, including all sub paths.
Cookiemanger.remove({
name : 'your_cookie_name',
domain : document.location.host
});
// Removes the cookie at the supplied path, excluding sub paths.
Cookiemanger.remove({
name : 'your_cookie_name',
path: '/'
});Testing a cookie against a certain value
Solution
For a "lightweight" cookie manager, there seems to be rather a lot going on in my opinion. And I'd call the object
I am however a bit suspicious of the
Speaking of regular expressions, that's probably the easiest way to parse the
That'll get you an object (or hash or map if you prefer) of all the cookies. You might also expose that as
Internally,
I wouldn't bother logging errors within the cookie manager, as you'll still have to check the return value elsewhere. In this case,
Now, for fuzzy name-matching, I'd add a
Once again, GIGO. Not necessarily your responsibility to check the arguments.
Lastly, I'd probably have
Another reason would be to keep it consistent with the
Again, not much reason to attempt to log, just to risk throwing an exception there; probably easier to just throw if the input is spurious.
CookieManager since it's two words, but that's not structurally/syntactically important.I am however a bit suspicious of the
get() usage. If I give it a string, and nothing else, I'd expect that to do strict name-matching. I.e. given a name, I expect zero or 1 cookie in return, not a list. Maybe break out the "fuzzy matching" into a find() method, or have get() accept a regular expression instead.Speaking of regular expressions, that's probably the easiest way to parse the
document.cookie string:function all() {
var cookies = {};
// using replace, as it accepts a function
document.cookie.replace(/([^=]+)=([^;]*)[;\s]*/g, function(match, name, value) {
cookies[name] = value;
});
return cookies;
}That'll get you an object (or hash or map if you prefer) of all the cookies. You might also expose that as
CookieManager.all() instead of overloading the get() method with yet another usage.Internally,
get() can use all() to get the individual cookies, and basically become a very simply shortcutfunction get(name) {
return all()[name];
}I wouldn't bother logging errors within the cookie manager, as you'll still have to check the return value elsewhere. In this case,
get() will simply return a string value or undefined. GIGO: Garbage in, garbage out.Now, for fuzzy name-matching, I'd add a
find() function to have something distinct from the stricter get() function. Something likefunction find(pattern) {
var name,
found = {},
cookies = all();
if( pattern instanceof RegExp ) {
for( name in cookies ) {
if( pattern.test(name) ) {
found[name] = cookies[name];
}
}
} else {
for( name in cookies ) {
if( name.indexOf(pattern) !== -1 ) {
found[name] = cookies[name];
}
}
}
return found;
}Once again, GIGO. Not necessarily your responsibility to check the arguments.
Lastly, I'd probably have
set() accept specific arguments, rather than an object simply because it makes its usage more obvious. If I just have to pass an object, I still have to know what that object should contain.Another reason would be to keep it consistent with the
remove() function, which takes specific arguments already.set() and remove() are the two functions that should probably do some input-checking and maybe throw an exception. This is mostly as they can't really follow the GIGO approach, because they don't return something. So it's more like "garbage in, throw exception"Again, not much reason to attempt to log, just to risk throwing an exception there; probably easier to just throw if the input is spurious.
Code Snippets
function all() {
var cookies = {};
// using replace, as it accepts a function
document.cookie.replace(/([^=]+)=([^;]*)[;\s]*/g, function(match, name, value) {
cookies[name] = value;
});
return cookies;
}function get(name) {
return all()[name];
}function find(pattern) {
var name,
found = {},
cookies = all();
if( pattern instanceof RegExp ) {
for( name in cookies ) {
if( pattern.test(name) ) {
found[name] = cookies[name];
}
}
} else {
for( name in cookies ) {
if( name.indexOf(pattern) !== -1 ) {
found[name] = cookies[name];
}
}
}
return found;
}Context
StackExchange Code Review Q#24513, answer score: 4
Revisions (0)
No revisions yet.