In any case, if one of these limits is reached, the cookie is simply not created the browser. This is fine, because web developer expects cookies to fail from time to time, and the system they develop has to cope with this unreliableness. However, this situation can sometimes become frustrating, and it is why I wanted to extend the default behavior of the jQuery Cookie plugin with a few more capabilities.
This extension to the jQuery Cookie plugin adds the capability to save content that is bigger than 4096 bytes long using two different mechanism: the usage of HTML5’s localStorage
, or the usage of a series of cookies where the content is chunked and saved. This extension is backward compatible with the jQuery Cookie plugin and its usage should be transparent to the users. Even if existing cookies have been created with the normal Cookie plugin, they will still be usable by this new extension. The usage syntax is the same, but 3 new options have been created.
Now, let’s see how this plugin works, how developers should use it, what are its limitations, etc.
You can immediately download the jQuery Extended Cookie plugin from here:
Limitations Of Cookies
First, let’s see what the RFC 2109 says about the limitations of cookies in web browsers. Browsers should normally have these implementation limits (see section 6.3):
Practical user agent implementations have limits on the number and size of cookies that they can store. In general, user agents' cookie support should have no fixed limits. They should strive to store as many frequently-used cookies as possible. Furthermore, general-use user agents should provide each of the following minimum capabilities individually, although not necessarily simultaneously: * at least 300 cookies * at least 4096 bytes per cookie (as measured by the size of the characters that comprise the cookie non-terminal in the syntax description of the Set-Cookie header) * at least 20 cookies per unique host or domain name User agents created for specific purposes or for limited-capacity devices should provide at least 20 cookies of 4096 bytes, to ensure that the user can interact with a session-based origin server. The information in a Set-Cookie response header must be retained in its entirety. If for some reason there is inadequate space to store the cookie, it must be discarded, not truncated. Applications should use as few and as small cookies as possible, and they should cope gracefully with the loss of a cookie.
New Options
Before I explains how this extension works, let me introduce three new options that have been added to the Cookie plugin. These new options will be put into context, and properly defined later in this blog post.
maxChunkSize
– This defines the maximum number of bytes that can be saved in a single cookie.(default: 3000)
maxNumberOfCookies -
This is the maximum number of cookies that can be created for a single domain name.(default: 20)
useLocalStorage
– This tells the extended Cookie plugin to use the HTML5’slocalStorage
capabilities of the browser instead of a cookie to save that value.(default: true)
How Does This Extension Works?
As I said in the introduction of this blog post, this extension to the jQuery Cookie plugin does two things:
- It uses the HTML5
localStorage
capabilities of the browser if this feature is available instead of relying on the cookies. However, if cookies are needed by the developer, this feature can be turned off with theuseLocalStorage = false
option - If the
localStorage
option is disable, or simply not available on a browser, and if the content is bigger than the limit of the size of a cookie, then this extension will chunk the input content, and save it in multiple cookies
If the useLocalStorage
is true
, then the plugin will try to see if the HTML5 localStorage
mechanism is available on the browser. If it is, then it will use that local storage to save and retrieve content to the browser. If it is not, then the plugin will act like if useLocalStorage
is false
and the process will continue by using cookies to save and read that content from the browser.
If useLocalStorage
is false
, or if the HTML5 localStorage
mechanism is not available on the browser, then the plugin will check if the content is bigger than the maxChunkSize
option, than all the chunks will be saved in different cookies until it reaches the limit imposed by the maxNumberOfCookies
option.
If cookies are used, then two use-cases can happen:
- The content is smaller than or equal to
maxChunkSize
- The content is bigger than
maxChunkSize
If the content is smaller than or equal to maxChunkSize
than only one cookie will be created by the browser. The name of the cookie will be the value provided to the key
parameter.
If the content is bigger than maxChunkSize
than multiple cookies will be created, one per chunk. The convention is that the name of the first cookie is the value provided to the key
parameter. The name of the other chunks is the value provided to the key
parameter with the chunk indicator ---ChunkNum
append to it. For example, if we have a cookie with a content of 10000 bytes that has maxChunkSize
defined to 4000 bytes, then these three cookies would be created:
cookie-name
cookie-name---1
cookie-name---2
Usage
Now, let’s see how this extended jQuery Cookie plugin should be used in your code. The usage of the extension is no different from the usage of the normal jQuery Cookie plugin. However, I am showing how to use the new options along with how to use the plugin in general.
Create a Cookie
Let’s create a cookie that expires in 365 days and where the path is the root:
[cc lang=’javascript’ ]
$.cookie(‘my-cookie’, “the-content-of-my-cookie”, { expires: 365, path: “/” });
[/cc]
By default, this value will be persisted in the localStorage
if the browser supports it, and not in a cookie. So, let’s see how to force the plugin to save the content in a cookie by using the useLocalStorage
option:
[cc lang=’javascript’ ]
$.cookie(‘my-cookie’, “the-content-of-my-cookie”, {useLocalStorage: false, expires: 365, path: “/” });
[/cc]
Delete a Cookie
Let’s see how a cookie can be deleted. The method is simply to put null
as the value of the cookie. This will instruct the plugin to remove the cookie.
[cc lang=’javascript’ ]
$.cookie(‘my-cookie’, null);
[/cc]
With that call, the plugin will try to remove my-cookie
both in the localStorage
and in the cookies
.
Read a Cookie
Let’s see how we can read the content of a cookie:
[cc lang=’javascript’ ]
var value = $.cookie(‘my-cookie’);
[/cc]
With this call, value
will get the content that has been saved in the localStorage
, or the cookies
. This will depend if the localStorage
was available in the browser.
Now, let’s see how to force reading the cookies by bypassing the localStorage
mechanism:
[cc lang=’javascript’ ]
var value = $.cookie(‘my-cookie’, {useLocalStorage: false});
[/cc]
Note that if the cookie is not existing for a key
, then the $.cookie()
function will return null
.
Using Limitations
Let’s see how to use the maxNumberOfCookies
and maxChunkSize
options to limit the size and the number of cookies to be created.
With this example, the content will be saved in multiple cookies of 1000 bytes each up to 30 cookies:
[cc lang=’javascript’ ]
var value = $.cookie(‘my-cookie’, “the-content-of-my-cookie-is-10000-bytes-long…”, {useLocalStorage: false, maxChunkSize  = 1000, maxNumberOfCookies = 30, expires: 365, path: “/” });
[/cc]
Limitations
Users have to be aware of the limitations of this enhanced plugin. Depending on the browser, the values of the maxChunkSize
and the maxNumberOfCookies
options should be different. In the worse case, some cookies (or cookies chunks) may simply not be created by the browser. As stated in the RFC 2109, the web applications have to take that fact into account, and be able to gracefully cope with this.
Future Enhancements
In the future, this extension should detect the browser where it runs, and setup the maxChunkSize
and the maxNumberOfCookies
parameters automatically depending on the cookies limitation of each browser.
Conclusion
I had to create this extension to the jQuery Cookie plugin to be able to store the resultsets returned by some web service endpoints. It is only used to limit the number of queries sent to these endpoints. Since the values returned by the endpoints are nearly static, that they are loaded at each page view and that they are a few kilobytes big, I had to find a way to save that information in the browser, and to overcome the size limitation of the cookies if possible. I also needed to be able to cope with older versions of browsers that only supports cookies. In the worse case scenario, the browser will simply send the request to the endpoints at each page load for the special use-cases where nothing works: not the cookies and not the localStorage
. But at least, my application will benefit of this enhancement from the 95% of the users were one of these solutions works.
Pawan Vora
February 2, 2012 — 11:33 am
Very interesting! I will have to try it out. A quick question: On what browsers have you tested the plug-in?
Frederick Giasson
February 2, 2012 — 11:38 am
Hi Pawan!
Tested: latest FireFox, Chrome, Safari and IE
The exact same browsers supported by the main jQuery cookie plugin should be supported. If the locaStorage feature is not available, it will simply use the cookies approach (and will chunk them if the value to save is too big). The only issues that may appears is if you reach the maximum number of cookie per domain, etc. But in any case, applications that uses cookies should handle these possibilities.
Please tell me if it works well on your side, if you find issues or have ideas for improvements! If any of this happen, I would encourage you to fork the GitHub project, and I will integrate any modifications that you could come-up with.
Thanks,
Take care,
Fred
TW
July 5, 2012 — 7:44 am
Hi, nice work on the extension.
I was just wondering if you have considered implementing a quota check before writing to the localstorage? If the browser’s localstorage quota is exceeded then the exception should probably be caught and handled.
Thanks again for sharing 🙂
Frederick Giasson
July 6, 2012 — 8:59 am
Hi TW!
That is not currently implemented. Right now, the only limit that is implemented in some ways, is the maximum number of cookies, per domain. Here is a good thread about the ways to implement that per major browsers:
http://stackoverflow.com/questions/3027142/calculating-usage-of-localstorage-space
I do not have time to upgrade that for now, so you can give it a try if you do, and I will pull the changes on the main project.
Thanks!
Fred
M4D
January 25, 2013 — 12:08 pm
Hello Frederick,
i have a question. Delete a Cookie didnt work by me on IE7.
i tried it so
$.cookie(val, null, { expires: 365});
or
$.cookie(val, null);
but it didnt work. can you help me please?