11402 sujets

JavaScript, DOM et API Web HTML5

Pages :
Bonjour.

J'ai fait une recherche sur le sujet des fonctions utiles et j'ai remarqué qu'il n'y a rien sur les cookies et comme je n'ai trouvé dans aucun sujet des fonctions pour gérer les cookies je me demandais si quelqu'un en a à nous proposer pour que l'on puisse mettre les meilleurs dans le topic des fonctions utiles.

Personnellement j'utilise celles que j'ai trouvé sur quirksmode : fonctions pour manipuler les cookies en javascript.
Personnellement, j'ai celle-ci :


/*
Retourne un objet qui contient toutes les valeurs de tous les cookies actuellement enregistrés.

@return Object Un objet contenant les valeurs des cookies est retourné.

L'objet retourné contient une propriété par cookie, et une fonction get qui permet d'obtenir la valeur d'un cookie. Si celui-ci n'existe pas, null est retourné.
*/
function getCookies () {
var tab = document.cookie.split(";");
var t = new Object();
var n = 0;
for (var i=0; i < tab.length; i++) {
var x = tab[i].split("=");
t[x[0]]=x[1];
t[i]=tab[i];
n++;
}
t.length = n;
t.get = function (name) {
if (t[name]) return t[name];
else return null;
}
return t;
}

[/i][/i][/i]
Intéressant car ta méthode permet de parcourir les cookies une seule fois contrairement à la fonction de quirksmode. Merci.

D'autres ?
Modifié par CNeo (30 Jul 2007 - 08:55)
Gatsu35 a écrit :
http://www.quirksmode.org/js/cookies.html et tu y trouveras 3 fonctions bien utiles sur les cookies
C'est celles que j'ai mis en lien dans mon premier message ... Smiley cligne
Édit de la fonction de QuentinC à cause du BBCode.
/*
Retourne un objet qui contient toutes les valeurs de tous les cookies actuellement enregistrés.

@return Object Un objet contenant les valeurs des cookies est retourné.

L'objet retourné contient une propriété par cookie, et une fonction get qui permet d'obtenir la valeur d'un cookie. Si celui-ci n'existe pas, null est retourné.
*/
function getCookies () {
var tab = document.cookie.split(";");
var t = new Object();
var n = 0;
for (var j=0; j < tab.length; j++) {
var x = tab[j].split("=");
t[x[0]]=x[1];
t[j]=tab[j];
n++;
}
t.length = n;
t.get = function (name) {
if (t[name]) return t[name];
else return null;
}
return t;
}
De nouveau une correction pour que "cookies.length" ne soit pas égal à "1" quand il n'y a rien.

function getCookies(){
 var cookies = new Object();
 var n = 0;
 if(document.cookie!=''){
  var tab = document.cookie.split(";");
  for (var j=0; j < tab.length; j++){
   var x = tab[j].split("=");
   cookies[x[0]]=x[1];
   n++;
  }
 }
 cookies.length = n;
 cookies.get = function (name){
  if (cookies[name]) return cookies[name];
  else return null;
 }
 return cookies;
}


Note : j'ai changé les noms pour moi mais j'ai la flemme de tout remettre comme avant.
Modifié par CNeo (30 Jul 2007 - 10:41)
Hello,

Personnellement j'utilise ceci :
var cookieMgr = {
  get: function(name) {
    var o = new RegExp(name + "=([^;]+)").exec(document.cookie);
    return o && unescape(o[1]);
  },

  set: function(name, value, days) {
    var expires = "";
    if (days) {
      expires = "; expires=" +
        new Date(new Date().getTime() + days*24*60*60*1000).toGMTString();
    }

    document.cookie = name + "=" + escape(value) + expires + "; path=/";
  }
};
QuentinC a écrit :
Personnellement, j'ai celle-ci :

Problème potentiel pour certaines valeurs (que l'on n'utilisera sans doute pas pour les noms de cookies) :
alert(getCookies().get("constructor"));
alert(getCookies().get("toString"));
// ...

Modifié par Julien Royer (30 Jul 2007 - 14:21)
a écrit :

Problème potentiel pour certaines valeurs (que l'on n'utilisera sans doute pas pour les noms de cookies) :

Certes.... j'ai pas pensé à ça mais c'est en effet peu probable

Merci pour la correction du bug si tableau vide, je n'y ai pas pensé non plus.


Sinon, j'ai ça aussi en stock :

eval(document.cookie.split(";").join("; ").replace(/=([^=;]*)/g, "=\"$1\"").replace(/=\"([0-9]+(\\.[0-9]+)?)\"/g, "=$1"));

Pas mal pour impressionner... ça crée des variables globales.
J'ai voulu faire un mixte entre la solution de QuentinC qui permet de ne pas parcourir tous les cookies à chaque fois que l'on chercher une valeur et celle de Julien avec un élégant objet.

Le problème c'est que ça ne marche pas. J'ai des données que je rentre dans un tableau et qui disparaissent, seule la première reste. Smiley biggol Étant donné que j'y ai passé une bonne partie de l'après-midi je suppose que ça doit être un comportement que je ne connais pas dû au fait d'utiliser un objet.

var cookies = {
 number: 0,
 tab: new Array(),

 initiate: function(){
  if(document.cookie!=''){
   var bar = document.cookie.split(";");
   for(var j=0; j<bar.length; j++){
    var foo = bar[j].split("=");
    cookies.tab[foo[0]]=foo[1].toString();
    cookies.number++;
   }
  }
 },

 get: function(varName){
  if(cookies.tab[varName]) return cookies.tab[varName];
  else return null;
 },

 set: function(varName, varValue, days){
  cookies.tab[varName]=varValue.toString();
  var expires = '';
  if(days){
   expires='; expires='+new Date(new Date().getTime() + days*24*60*60*1000).toGMTString();
  }
  document.cookie = varName+"="+varValue+expires+';path=/';
 },

 erase: function(varName){
  cookies.set(varName,'',-1);
  cookies.tab[varName]='';
 }
};
cookies.initiate();


Quand je teste dans la fonction initiate les valeurs alors elles sont là mais quand je teste n'importe où ailleurs que se soit à l'intérieur ou à l'extérieur de l'objet seule la première valeur rentrée est accessible.

Quelqu'un aurait-il une idée ?
Modifié par CNeo (31 Jul 2007 - 09:22)
Ça ne change rien.

Attendez j'ai trouvé je vais expliquer.
Modifié par CNeo (31 Jul 2007 - 09:32)
En fait c'était tout con : "document.cookie" revoie une chaîne qui pour séparer chaque valeur utilise les deux caractères "; " et pas seulement ";".

Voilà donc le code :
var cookies = {
 number: 0,
 tab: new Array(),

 initiate: function(){
  if(document.cookie!=''){
   var bar = document.cookie.split("; ");
   for(var j=0; j<bar.length; j++){
    var foo = bar[j].split("=");
    this.tab[foo[0]]=foo[1].toString();
    this.number++;
   }
  }
 },

 get: function(varName){
  if(this.tab[varName]) return this.tab[varName];
  else return null;
 },

 set: function(varName, varValue, days){
  this.tab[varName]=varValue.toString();
  var expires = '';
  if(days){
   expires='; expires='+new Date(new Date().getTime() + days*24*60*60*1000).toGMTString();
  }
  document.cookie = varName+"="+varValue+expires+';path=/';
 },

 erase: function(varName){
  this.set(varName,'',-1);
  this.tab[varName]='';
 }
};
cookies.initiate();


Maintenant il faudrait savoir laquelle on va mettre dans les fonctions utiles ?
Modifié par CNeo (31 Jul 2007 - 09:46)
Pour que ce soit un peu plus portable, je remplacerais cette ligne :
   var bar = document.cookie.split("; "); 

par :
   var bar = document.cookie.split(/\s*;\s*/g);

Parce qu'apparament l'espace suppplémentaire n'est pas présent partout ni avec tous les navigateurs. En tout cas je n'ai jamais eu de problème avec ça.
Voici ma proposition :
var cookieMgr = {
  get: function(name) {
    var o = new RegExp(name + "=([^;]+)").exec(document.cookie);
    return o && unescape(o[1]);
  },

  set: function(name, value, days) {
    var expires = "";
    if (days) {
      expires = "; expires=" +
        new Date(new Date().getTime() + days*24*60*60*1000).toGMTString();
    }

    document.cookie = name + "=" + escape(value) + expires + "; path=/";
  },

  erase: function(name) {
    this.set(name, "", -1);
  }
};

Petites précisions :
- A mon avis, l'utilisation de escape et unescape est importante.
- Je ne suis pas très favorable à la mise en cache de tous les cookies, étant donné que l'utilisateur peut les modifier ailleurs dans son code sans passer par nos fonctions.

<edit>Suppression de getAll qui ne fonctionnait pas sous IE.
Modifié par Julien Royer (31 Jul 2007 - 15:27)
Pourquoi l'utilisateur irait modifier des cookies ?
Franchement la mise en cache fait à mon avis gagné du temps d'exécution.
De plus tu utilises deux fois des regexp ceux qui ralenti encore le script ( à moins qu'en Javascript ce ne soit pas pareil qu'en PHP ? ).

Ensuite il suffit de réfléchir un peu pour se rende compte que normalement il n'y a rien de super important dans des cookies ( le pourquoi de ce sujet vient d'une utilisation sur des menus pour savoir s'ils sont masqués ou non ) donc si la valeur est modifié par l'utilisateur c'est son problème ...

Édit : pour le "escape" ça peut peut-être servir je le rajoute dans la mienne.
Modifié par CNeo (31 Jul 2007 - 11:18)
CNeo a écrit :
Pourquoi l'utilisateur irait modifier des cookies ?

Il se peut que plusieurs scripts s'exécutent en même temps sur ta page, dont certains que tu ne maîtrises pas...
CNeo a écrit :
De plus tu utilises deux fois des regexp ceux qui ralenti encore le script ( à moins qu'en Javascript ce ne soit pas pareil qu'en PHP ? ).

Le fait que les regexp soient plus lentes que l'utilisation de split reste à prouver.
CNeo a écrit :
( le pourquoi de ce sujet vient d'une utilisation sur des menus pour savoir s'ils sont masqués ou non )

Peut-être, mais le pourquoi a peu d'importance, il me semble que le but du sujet est bien de proposer des fonctions utilisables ailleurs.

Franchement, je ne suis pas convaincu que le temps d'exécution gagné vaille vraiment la peine de se compliquer la vie avec une mise en cache. Si l'utilisateur des fonctions souhaite gagner du temps, il peut très bien mettre lui-même en cache l'objet que lui a retourné la fonction.
Julien Royer a écrit :
Il se peut que plusieurs scripts s'exécutent en même temps sur ta page, dont certains que tu ne maîtrises pas...
Ce n'est pas le cas dans mon projet actuel.
Julien Royer a écrit :
Le fait que les regexp soient plus lentes que l'utilisation de split reste à prouver.
En PHP il me semble que les regexp sont plutôt lentes mais j'avoue que pour le Javascript je ne sais pas.
Julien Royer a écrit :
Peut-être, mais le pourquoi a peu d'importance, il me semble que le but du sujet est bien de proposer des fonctions utilisables ailleurs.
Oui c'est bien le but.
Julien Royer a écrit :
Franchement, je ne suis pas convaincu que le temps d'exécution gagné vaille vraiment la peine de se compliquer la vie avec une mise en cache. Si l'utilisateur des fonctions souhaite gagner du temps, il peut très bien mettre lui-même en cache l'objet que lui a retourné la fonction.
Tu sais ce qu'on dit : "1ms+1ms+1ms..." et aussi le fameux "il n'y a pas de petits gestes quand on est 60 millions à les faire" qui s'applique bien en informatique aussi.

Je pense que nos deux objets répondent à deux demandes différentes donc soit on met les deux soit on ne met que la tienne c'est à toi de décider en sachant que de toute façon il restera ce sujet comme trace et qu'il peut-être mis en lien.
CNeo a écrit :
En PHP il me semble que les regexp sont plutôt lentes mais j'avoue que pour le Javascript je ne sais pas.

Moi non plus, c'est à tester.
CNeo a écrit :
Tu sais ce qu'on dit : "1ms+1ms+1ms..." et aussi le fameux "il n'y a pas de petits gestes quand on est 60 millions à les faire" qui s'applique bien en informatique aussi.

Je sais surtout que :
Donald Knuth a écrit :
L'optimisation prématurée est la source de tous les maux.

(voir sur Wikipédia)
et je pense que c'est bien plus important pour être un bon programmeur. Smiley smile
CNeo a écrit :
Je pense que nos deux objets répondent à deux demandes différentes donc soit on met les deux soit on ne met que la tienne c'est à toi de décider en sachant que de toute façon il restera ce sujet comme trace et qu'il peut-être mis en lien.

Je suis bien d'accord. Par contre, pourquoi n'émets-tu pas l'hypothèse de ne mettre que le tien ? Pour ma part, je pense que l'on peut mettre les deux.
Pages :