263 votes

Fonction plus court pour la lecture d’un cookie en JavaScript

Quel est le plus court, précis, et de la croix-navigateur compatible méthode pour la lecture d'un cookie en JavaScript?

Très souvent, lors de la construction de scripts autonomes (où je ne peux pas avoir tout à l'extérieur de dépendances), je me retrouve à l'ajout d'une fonction pour lire des cookies, et, habituellement, de repli sur l' QuirksMode.org readCookie() méthode (280 octets, 216 minimisé.)

function readCookie(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;
}

Il fait le travail, mais son laid, et ajoute un peu de ballonnement à chaque fois.

La méthode jQuery.cookie utilise quelque chose comme ceci (modifié, 165 octets, 125 minifiés):

function read_cookie(key)
{
    var result;
    return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? (result[1]) : null;
}

Remarque ce n'est pas un " Code de Golf de la concurrence: je suis légitimement intéressés par la réduction de la taille de mon readCookie fonction, et de garantir que la solution que j'ai est valide.

346voto

Mac Points 1

Plus courte, plus fiable et plus performant que l'actuel best-voté réponse:

function getCookieValue(a, b) {
    b = document.cookie.match('(^|;)\\s*' + a + '\\s*=\\s*([^;]+)');
    return b ? b.pop() : '';
}

Une comparaison des performances des différentes approches est montré ici:

http://jsperf.com/get-cookie-value-regex-vs-array-functions

Quelques notes sur l'approche:

La regex approche n'est pas seulement le plus rapide, il donne la plus courte de la fonction. En outre, il convient de rappeler que, selon l' officiel spec (RFC 2109), l'espace après le point-virgule qui sépare les cookies dans le document.cookie est facultatif et un argument peut être faite que ça ne doit pas être invoqué. En outre, les espaces sont autorisés, avant et après le signe égal (=) et un argument peut être faite que ce potentiel, les espaces doivent être pris en compte dans aucun document fiable.témoin de l'analyseur. L'expression régulière ci-dessus tient compte à la fois de la ci-dessus les espaces conditions.

199voto

zyklus Points 31683

Cela ne sera jamais frappé document.témoin d'UN temps. Chaque demande sera instantanément.

(function(){
    var cookies;

    function readCookie(name,c,C,i){
        if(cookies){ return cookies[name]; }

        c = document.cookie.split('; ');
        cookies = {};

        for(i=c.length-1; i>=0; i--){
           C = c[i].split('=');
           cookies[C[0]] = C[1];
        }

        return cookies[name];
    }

    window.readCookie = readCookie; // or expose it however you want
})();

J'ai peur, il n'y a vraiment pas un moyen plus rapide de cette logique générale, à moins que vous êtes libre d'utiliser .forEach navigateur dépendantes (même alors, vous n'êtes pas de sauver beaucoup)

Votre propre exemple légèrement comprimé d' 120 bytes:

function read_cookie(k,r){return(r=RegExp('(^|; )'+encodeURIComponent(k)+'=([^;]*)').exec(document.cookie))?r[2]:null;}

Vous pouvez l'obtenir à l' 110 bytes si vous en faites une 1-lettre du nom de la fonction, 90 bytes si vous déposez encodeURIComponent.

J'ai obtenu vers le bas à l' 73 bytes, mais pour être juste il est 82 bytes si elle est nommée en readCookie et 102 bytes lorsque l'ajout d' encodeURIComponent:

function C(k){return(document.cookie.match('(^|; )'+k+'=([^;]*)')||0)[2]}

24voto

Jeffery To Points 9225

Hypothèses

Basé sur la question, je pense que certaines hypothèses / exigences requises pour cette fonction sont:

  • Il sera utilisé comme une fonction de la bibliothèque, et donc destinés à être déposés dans toute la base de code;
  • En tant que tel, il sera nécessaire de travailler dans de nombreux environnements différents, c'est à dire travailler avec l'héritage du code JS, des Sgc de différents niveaux de qualité, etc.;
  • À inter-opérer avec le code écrit par d'autres personnes et/ou le code que vous n'avez pas le contrôle, la fonction ne devrait pas faire d'hypothèses sur la façon dont les noms de biscuit ou les valeurs sont codées. L'appel de la fonction avec une chaîne de caractères "foo:bar[0]" doit retourner un cookie (littéralement) nommé "foo:bar[0]";
  • De nouveaux cookies peuvent être écrites et/ou les cookies existants modifiés à tout moment pendant la durée de vie de la page.

Sous ces hypothèses, il est clair qu' encodeURIComponent / decodeURIComponent ne doit pas être utilisé; cela suppose que le code que définir le cookie également codée à l'aide de ces fonctions.

L'expression régulière approche devient problématique si le nom du cookie peut contenir des caractères spéciaux. jQuery.cookie contourne ce problème en codant le nom de cookie (en fait à la fois le nom et la valeur) lorsque le stockage d'un cookie, et le décodage du nom lors de la récupération d'un cookie. Une expression régulière solution est ci-dessous.

Sauf si vous êtes seulement de lire les cookies que vous avez complètement le contrôle, il serait également souhaitable de lire les témoins de document.cookie directement et de ne pas mettre en cache les résultats, car il n'y a aucun moyen de savoir si le cache n'est pas valide sans la lecture d' document.cookie de nouveau.

(Alors que l'accès et l'analyse document.cookies sera légèrement plus lent que d'utiliser un cache, il ne serait pas aussi lente que la lecture d'autres parties du DOM, car les cookies ne jouent pas un rôle dans les DOM / rendu des arbres.)


Boucle de fonction

Voici le Code de Golf de réponse, basée sur PPK (boucle) fonction:

function readCookie(name) {
    name += '=';
    for (var ca = document.cookie.split(/;\s*/), i = ca.length - 1; i >= 0; i--)
        if (!ca[i].indexOf(name))
            return ca[i].replace(name, '');
}

qui quand minifiés, vient à 128 caractères (sans compter le nom de la fonction):

function readCookie(n){n+='=';for(var a=document.cookie.split(/;\s*/),i=a.length-1;i>=0;i--)if(!a[i].indexOf(n))return a[i].replace(n,'');}

Expression régulière fonction

Mise à jour: Si vous voulez vraiment une expression régulière solution:

function readCookie(name) {
    return (name = new RegExp('(?:^|;\\s*)' + ('' + name).replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') + '=([^;]*)').exec(document.cookie)) && name[1];
}

Cela échappe les caractères spéciaux dans le nom du cookie avant la construction de l'objet RegExp. Minifiés, cela revient à 134 caractères (sans compter le nom de la fonction):

function readCookie(n){return(n=new RegExp('(?:^|;\\s*)'+(''+n).replace(/[-[\]{}()*+?.,\\^$|#\s]/g,'\\$&')+'=([^;]*)').exec(document.cookie))&&n[1];}

Comme Rudu et cwolves l'avons souligné dans les commentaires, l'expression régulière d'échappement des regex peut être raccourcie de quelques caractères. Je pense qu'il serait bon de garder la trajectoire de la regex cohérente (vous pouvez l'utiliser ailleurs), mais leurs suggestions sont à envisager.


Notes

Ces deux fonctions, de ne pas manipuler null ou undefined, c'est à dire si il y a un cookie nommé "null", readCookie(null) sera de retour à sa valeur. Si vous avez besoin pour gérer ce cas, d'adapter le code en conséquence.

18voto

user1998323 Points 51

Code de google analytique ga.js

10voto

Simon Steinberger Points 1787

Que diriez-vous celui-ci ?

Compté 89 octets sans le nom de la fonction.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X