0

On my website I use a cookie to show or hide certain content. Depending on how users log in will determine what content is visible to them. i.e. If I log in with Facebook, my site looks for a cookie called "fbsr_3324". My problem is that the second part of the cookie name changes for every user (fbsr_2889 fbsr_9902 etc). I therefore want to know if someone can help and suggest how I can check for only the first part of the cookie name (i.e. only look for the existance of cookies starting with fbsr_

Here is the current current Javascript I use:

function checkCookie() {
    contentDiv=document.getElementById("cookieFb");
    if (document.cookie.indexOf("fbsr_")!=-1) {
        contentDiv.style.display="none";
    }
    else {
        contentDiv.style.display="block";
    }
}
6
  • It's possible to do it, but it's probable better to just have a cookie with the name fbsr and the value 2289. Any key value store is most useful if you know the keys in advance. Commented Jul 31, 2013 at 14:07
  • I agree, but the problem is that it is the cookie is generated from from the "Login with Facebook" extension, so I can't change the names of the cookies that are generated Commented Jul 31, 2013 at 14:09
  • Maybe this could help: document.cookie.split(/; */).map(function(c){return c.split('=')[0];}) That should give you array of the cookie names only, without values. Commented Jul 31, 2013 at 14:12
  • @Paulpro: What about cookiename=foobar; expires=<some-date>; path=/;? you'd map the expiry dates and paths as cookies, too. and not all browsers support the map method yet Commented Jul 31, 2013 at 14:17
  • @EliasVanOotegem map is one of those functions you can expect everyone to have a SHIM for, but you have a good point about expires and path. Commented Jul 31, 2013 at 14:25

2 Answers 2

2

The code you're currently using would perform as if I were logged in using facebook, if I had a cookie set containing the value 'fbsr_haha, gotcha'
Perhaps this is a job for regex:

/^|;\s*fbsr_[0-9]{4}\=[^;]+;/.test(document.cookie);

Should do the trick.
Expression explanation:

  • ^|;: Either start of the string, or a semi-colon
  • \s*: followed by zero or more spacces
  • fbsr_[0-9]{4}: matches fsbr_ and any sequence of 4 numbers
  • \=: you could just write =, but sometimes you need to escape = (lookarounds), so best escape it once too often than not enough
  • [^;]+ anything but a semi-colon at least once or more
  • ;: a literal semi-colon

Where to use this expression:

function checkCookie()
{
    contentDiv=document.getElementById("cookieFb");
    if (/^|;\s*fbsr_[0-9]{4}\=[^;]+;/.test(document.cookie))
    {//facebooker!
        contentDiv.style.display="none";
        return;//return here, so you can leve the else out
    }
    contentDiv.style.display="block";
}

Well, that should do it.
However, I can't help myself, so if ever you get more familiar with JS, and feel like optimizing some of your scripts, consider this:

var checkCookie = (function(expr)
{
    var contentDiv = document.getElementById('cookieFb');
    return function()
    {
        contentDiv.style.display="block";
        if (expr.test(document.cookie))
        {
            contentDiv.style.display="none";
        }
    };
}(/^|;\s*fbsr_[0-9]{4}\=[^;]+;/));

This is an optimized version of the exact same code you have. ATM, your code will query the dom for an element with the ID cookieFb every time it is called, and it'll create an instance of RegExp, too. By using a closure, you can query the DOM once, and create the instance of RegExp once, and re-use it for each call.
It's a bit more efficient, and micro-optimization in this case, but I couldn't help myself ;)

Sign up to request clarification or add additional context in comments.

5 Comments

Hi Elias. Thanks for your answer. Please excuse my utter stupidity, but I don't have much experience in Javascript. I know the expression you refer to, but where will this fit in with what I have? Again, sorry :(
@imieliei: updated, added 2 versions of the same function. For now, the first version is what you want, unless you understand what the second version does, and how to use it.
You truly are amazing. Thank you so much! I have another question though. In the /^|;\s*fbsr_[0-9]{4}\=[^;]+;/.test(document.cookie), where did you get the "test" from. Just wondering as I'm trying to see what is happening ad why. (It all works now, just wondering about the inner workings)
test is a method of the RegExp prototype. /something/ is a regular expression literal, and is, therefore an object check MDN on the method and on RegExp in general for more details
Ah I see!! First one makes sense now, but that second one I'm struggling to wrap my head around. One day I shall slay this Javascript dragon!
0

I would do this. First break all cookies into an associative array

Edit

Function scraped from here

function get_cookies_array() {

    var cookies = { };

    if (document.cookie && document.cookie != '') {
        var split = document.cookie.split(';');
        for (var i = 0; i < split.length; i++) {
            var name_value = split[i].split("=");
            name_value[0] = name_value[0].replace(/^ /, '');
            cookies[decodeURIComponent(name_value[0])] = decodeURIComponent(name_value[1]);
        }
    }

    return cookies;
}

then in your checkCookie function loop through all cookie names and see if any starts with fbsr_

function checkCookie() {
    var contentDiv=document.getElementById("cookieFb");
    var cookies = get_cookies_array();

    contentDiv.style.display="none";
    for(var name in cookies) {
        if (name.indexOf("fbsr_")==0) {
            contentDiv.style.display="block";
        }
    }
}

7 Comments

JS doesn't know of assoc arrays, it has Objects, and an Array is just an augmented version of that base Object constructor (Object.getPrototypeOF(Object.getPrototypeOf([])) in console shows that)
The solution works, independantly of how assoc arrays work internally in javascript...
Associative arrays just don't exist, it's either an Array instance or an object. Besides, your solution isn't full-proof. If I were to have a cookie fbsr_a, you'd consider that to be a FB cookie. You're also violating the few naming conventions JS has (getCookieArray instead of get_cookie_array, or better still getCookieObject)
Still, this is just nitpicking at code that basically works... (1) The function get_cookie_array was scraped from another site. (2) If I can't trust fbsr_a to be a FB cookie, then why should I trust fbsr_1234 to be a FB cookie? It's just a name and any site can create a cookie with whatever name they want. There's the same likehood that site X created a cookie named fbsr_a or fbsr_1234.
(1) If the code was taken from another site, you should mention your sources. If not, you're violating any license that might be out there. Even so, if a cookie looks like name=value=123;, the code fails. However unlikely, expect the unexpected... (2) That's true, but fbsr_a doesn't even look like a fb cookie, which follows the pattern fbsr_\d{4}, IMO, that's more than a trust-issue, I'd call that an omission that is easily rectified
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.