Chrome annoyances

by Developer @ pebbl.co.uk on Friday, 23 September 2011

Having just recently finished my part of quite a large scale multi-lingual campaign, I thought I should write a bit about the browser that caused the most development hassle. And for once it wasn't Internet Explorer. Thankfully for this campaign we had no directive to support IE6, which meant a lot of the usual IE problems went away. No, this time around it was Chrome, which was entirely unexpected... as whenever I've used the browser to test my own more simplified projects I've not come across many problems.

The truth is I don't really use Chrome as a browser, I'm still a FireFox guy (despite it getting slightly cumbersome). There are quite a few reasons for this, but mostly it's down to a few simple differences:


  1. I love the way FireFox's Awsome bar works... in my mind it is the only address bar that does what you'd intuitively expect
  2. I don't like the way Chrome requires the http:// part to be typed in order to find localhost domains
  3. Chrome still has a number of quite visible graphical and UI glitches - i.e. whilst typing an address immediately after boot up, it will ignore the address and open a blank tab.
  4. Chrome handles reposting data to pages (retry, cancel) in a terrible way IMO. It displays an error page on which the user has to refresh before they are asked to resend the data.
  5. Chrome seems to have no "Force Refresh" method that will wipe caches.

As you can see, small gripes. However, it's only from actually using the browser a bit more recently (in testing this project) that other annoyances have sprung up.


Chrome & Caching


For most browsers it is enough to include the following to prevent a page from being cached:


<meta http-equiv="Pragma" content="no-cache" />

It seems not so for Chrome, our UAT testers had been having an interesting time with the ability to navigate back after a form submit and being able to resubmit the entire form content again (without any retyping). Now this might sound like a good thing to have for certain forms - depending on their function - however our form is used for the entry to a competition, which utilises file uploads. Once the user has entered with certain content, there is no benefit for them to go back to the previous form and have it retain what they just submitted, in fact there are negative repercussions. All other browsers were doing what they were supposed to do, which is re-request the "navigated back to" page at which point the server redirects them back to the start of the submission process. The only way to get this to work in multiple versions of chrome was the following:


<meta http-equiv="Cache-Control" content="no-store" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />

and...


header("Content-type: text/html; charset=utf-8");
header("Cache-Control: no-store, must-revalidate");
header("Expires: Sun, 03 Jan 1982 00:00:00 GMT");

which seems just a little over the top. I'll probably find somewhere that it is actually stated in the standards, or some other nonsense like that... who writes these standards anyway.


Chrome & Session/Cookie setting


Chrome seems to have some problems with setting cookies, either that or Chrome is the only browser following what the actual specifications should be. I'm not sure, and I haven't had time to find out, considering my work hours recently. The same problem occured twice on the same project but for two different developers.


Basically we were getting session problems but only in Chrome. Now, usually if it had been bespoke code that was powering the Session handling I would have assumed programmer error. However we were using CodeIgniter which is a tried and tested code-base. So I went about debbugging everything I could think of that may cause problems with sessions that lay outside of the code. It took... a while... but turned up nothing. Then I stepped through the code function by function.. only to find everything was doing what it should.


By now I was getting rather wound up... all I was left with was trying to debug the browser difference itself. So I tried tracking the actual cookie creation (something that I had assumed would just be working). And guess what...? After all that, Chrome was - for some reason - ignoring the session cookie entirely. It was being sent, Chrome was recieving, but it was just ignoring it.

To cut a long story short... the thing that was causing a problem was the fact that whilst building our site we were accessing the staging server directly by I.P address (not something that i've done in the past) and both myself and the other back-end developer had both done the same thing, we'd automatically followed CodeIgniters advice and implemented something I usually do anyway (as part of security when settings cookies). You'll find the following in CI's config file:


/*
|--------------------------------------------------------------------------
| Cookie Related Variables
|--------------------------------------------------------------------------
|
| 'cookie_prefix' = Set a prefix if you need to avoid collisions
| 'cookie_domain' = Set to .your-domain.com for site-wide cookies
| 'cookie_path'   =  Typically will be a forward slash
| 'cookie_secure' =  Cookies will only be set if a secure HTTPS connection exists.
|
*/
$config['cookie_prefix']    = "";
$config['cookie_domain'] = ".".$_SERVER["HTTP_HOST"];
$config['cookie_path']      = "/";

By prefixing the host with a dot, you are making certain that no one else can access/modify your cookie if they have control of a domain that ends with the same name. For example:


If using the following as the host setting for a cookie:

www.pebbl.co.uk

It is possible that the cookie could be hijacked from:

hijackwww.pebbl.co.uk

or even:

pebbl.co.uk

would be hijacked with:

sneakypebbl.co.uk

You should be using the following:

.www.pebbl.co.uk
.pebbl.co.uk

All because hosts are compared from the right, pretty much like an "ends with" match - this is a useful feature that allows you to set cookies that can be accessed across multiple subdomains/CNAMEs. Obviously the first example isn't likely to happen with hijackwww.pebbl.co.uk as I have full control of my nameserver/dns settings and I'm not likely to go hijacking my own site. However on shared domains, or other set-ups this is indeed possible. The second example is also much more likely and can be achieve just by registering the right domain.


This is why CodeIgniter advise "Set to .your-domain.com for site-wide cookies". The prepended dot prevents the comparison from matching. This was all fully understood by me, so I didn't give it a second thought. However, I didn't think about whether this is expected behaviour when the hostname is not a domain name. Which is exactly what we ended up with when accessing the site using an I.P address.


In Firefox, Opera, Internet Explorer and it seems Safari... they all accept cookies from the following (note the prefixed dot):


.11.22.33.44

Chrome however, does not, now I don't now if it should or not... but all I can say is that it was a damnably annoying bug to track down. So whatever the choice, all the browsers should sort it out an do the same thing! Whereas I will always recomend using a proper domain name. We only stuck with the I.P to save time, and in the end it caused more problems than it shoud have done.


After re-reading my post I just realised that I'm not very clear at the end (like a lot of things really) ;) Basically our solution to the problem was to preg_match the HOST. If we were dealing with an I.P. then we don't prefix the cookie's host with a dot. I also made a note to myself to research exactly whether this is a bug in Chrome.

Leave your comment