Hypothèses
Sur la base de la question, je pense que certaines hypothèses / exigences pour cette fonction comprennent:
- Il sera utilisé comme une fonction de bibliothèque , et donc destiné à être déposé dans n'importe quelle base de code;
- En tant que tel, il devra fonctionner dans de nombreux environnements différents , c'est-à-dire travailler avec du code JS hérité, des CMS de différents niveaux de qualité, etc.
- Pour interagir avec du code écrit par d'autres personnes et / ou du code que vous ne contrôlez pas, la fonction ne doit faire aucune hypothèse sur la manière dont les noms ou les valeurs des cookies sont encodés . L'appel de la fonction avec une chaîne
"foo:bar[0]"
doit renvoyer un cookie (littéralement) nommé "foo: bar [0]";
- De nouveaux cookies peuvent être écrits et / ou des cookies existants modifiés à tout moment pendant la durée de vie de la page.
Sous ces hypothèses, il est clair que encodeURIComponent
/ decodeURIComponent
ne doit pas être utilisé ; cela suppose que le code qui a défini le cookie l'a également codé à l'aide de ces fonctions.
L'approche par expression régulière pose problème si le nom du cookie peut contenir des caractères spéciaux. jQuery.cookie contourne ce problème en codant le nom du cookie (en fait à la fois le nom et la valeur) lors du stockage d'un cookie et en décodant le nom lors de la récupération d'un cookie. Une solution d'expression régulière est ci-dessous.
À moins que vous ne lisiez que les cookies que vous contrôlez complètement, il serait également conseillé de lire document.cookie
directement les cookies et de ne pas mettre en cache les résultats, car il n'y a aucun moyen de savoir si le cache est invalide sans le relire document.cookie
.
(Bien que l'accès et l'analyse document.cookies
soient légèrement plus lents que l'utilisation d'un cache, ce ne serait pas aussi lent que la lecture d'autres parties du DOM, car les cookies ne jouent pas de rôle dans les arbres DOM / rendu.)
Fonction basée sur la boucle
Voici la réponse Code Golf, basée sur la fonction PPK (basée sur la boucle):
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 une fois minifié, arrive à 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,'');}
Fonction basée sur des expressions régulières
Mise à jour: si vous voulez vraiment une solution d'expression régulière:
function readCookie(name) {
return (name = new RegExp('(?:^|;\\s*)' + ('' + name).replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') + '=([^;]*)').exec(document.cookie)) && name[1];
}
Cela échappe tous les caractères spéciaux dans le nom du cookie avant de construire l'objet RegExp. Minifié, 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'ont souligné dans les commentaires, l'expression régulière d'échappement d'expressions régulières peut être raccourcie de quelques caractères. Je pense que ce serait bien de garder la règle d'échappement cohérente (vous l'utilisez peut-être ailleurs), mais leurs suggestions valent la peine d'être prises en compte.
Remarques
Ces deux fonctions ne gèrent pas null
ou undefined
, c'est-à-dire s'il y a un cookie nommé "null", readCookie(null)
renverront sa valeur. Si vous devez gérer ce cas, adaptez le code en conséquence.