We're running a virtual hackathon and you're invited! Learn more & join us now!
in Platform Updates

Setting Cookies to Subdomains in JavaScript

Bartosz Olchówka in Programming, on December 17, 2014

Setting cookies to subdomains can be very tricky. We’ve recently faced a problem of setting a cookie from foo.mycompany.com to all subdomains in a *.mycompany.com domain.

The solution seemed pretty straightforward: just set a wildcard cookie to .mycompany.com (note that the first character is a dot). However, we had to determine the target domain (the actual value of ”.mycompany.com”) automatically because our code is fired on tens of thousands of different domains.

And here came the problem: the list of Top-Level Domains.

Top-Level Domains and cookies

Let’s consider two similar domains:

  • foo.bar.com
  • foo.co.uk

JavaScript allows you to set a cookie available to all bar.com subdomains from within the foo.bar.com subdomain.

However, it won’t let you set a cookie to all co.uk subdomains from within the foo.co.ok subdomain because co.uk is a Top-Level Domain. If it was possible, your browser would send that cookie to all websites available in the British (co.uk) domain.

Web browsers don’t offer a way to check if the given string is a Top-Level Domain or not. If such a feature existed, it would help us determine if we can set a cookie to .co.uk (which we can’t) or .bar.com (which we can).

List of TLDs in your app (not recommended)

One of the solutions is to store a list of all Top-Level Domains in your app and check your domain against this list. Mozilla Foundation hosts a project called Public Suffix List which stores all TLD names in one place.

But in reality, keeping the list in your app is just a pain in the ass.

The “try and check” method (recommended)

There’s an easier solution though: just set a cookie to the domain and check if the browser actually set that cookie. If it didn’t, it’s a Top-Level Domain and we need to try setting a cookie to a subdomain.

Here’s a working example of the code that sets the cookie and copes with the mentioned TLD problem. It’s a modification of the renowned code snippet from an article about cookies on QuirksMode:

var Cookie =
{
   set: function(name, value, days)
   {
      var domain, domainParts, date, expires, host;

      if (days)
      {
         date = new Date();
         date.setTime(date.getTime()+(days*24*60*60*1000));
         expires = "; expires="+date.toGMTString();
      }
      else
      {
         expires = "";
      }

      host = location.host;
      if (host.split('.').length === 1)
      {
         // no "." in a domain - it's localhost or something similar
         document.cookie = name+"="+value+expires+"; path=/";
      }
      else
      {
         // Remember the cookie on all subdomains.
          //
         // Start with trying to set cookie to the top domain.
         // (example: if user is on foo.com, try to set
         //  cookie to domain ".com")
         //
         // If the cookie will not be set, it means ".com"
         // is a top level domain and we need to
         // set the cookie to ".foo.com"
         domainParts = host.split('.');
         domainParts.shift();
         domain = '.'+domainParts.join('.');

         document.cookie = name+"="+value+expires+"; path=/; domain="+domain;

         // check if cookie was successfuly set to the given domain
         // (otherwise it was a Top-Level Domain)
         if (Cookie.get(name) == null || Cookie.get(name) != value)
         {
            // append "." to current domain
            domain = '.'+host;
            document.cookie = name+"="+value+expires+"; path=/; domain="+domain;
         }
      }
   },

   get: function(name)
   {
      var nameEQ = name + "=";
      var ca = document.cookie.split(';');
      for (var i=0; i < ca.length; i++)
      {
         var c = ca[i];
         while (c.charAt(0)==' ')
         {
            c = c.substring(1,c.length);
         }

         if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
      }
      return null;
   },

   erase: function(name)
   {
      Cookie.set(name, '', -1);
   }
};

And here’s how to use it:

Cookie.set('test', '123');

When we are on foo.bar.com domain, the cookie will be available on *.bar.com subdomains.

But when we are on foo.co.uk domain, the cookie will be available on *.foo.co.uk subdomains.

This code works fine on our production environment on thousands of different domains. It’s way easier than storing the list of Top-Level Domains and comparing the current domain to the ones on the list.

See other Platform Updates

How Tissot Watch Notifies About a Weak Battery

Watches usually don’t have a digital display which shows a battery status icon.

Read more

What is SPF - Sender Policy Framework

Spoofing is a type of a computer attack in which the attacker pretends to be someone else.

Read more
See all updates