IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

LocalStorage incomplet lorsque plusieurs onglets [API HTML5]


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut LocalStorage incomplet lorsque plusieurs onglets
    Bonjour,


    J'essaye d'utiliser localStorage pour partager des données entre plusieurs onglets.

    Sur chaque onglets, j'affiche le contenu du localStorage: console.log(localStorage);.
    Pour éviter des mauvaises surprises, j'affiche aussi les modifications sur le storage avec un Script placé en début de mon fichier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    window.addEventListener('storage',function(e){
                console.log("MODIFIED !!!!!!!!"); 
                console.log(e);
    });
    Je modifie un élément du localStorage avec la méthode suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    class CLASS {
     
       __method(method = undefined) {
     
            let name = '123456';
     
            if(method === undefined) {
                console.log('get ' + localStorage.getItem(name));
                return localStorage.getItem(name);
            }
     
            this.prevMethod = method;
     
            if(method === null) {
                console.log('remove ');
                localStorage.removeItem(name);
                return;
            }
            console.log('set ' + method);
            localStorage.setItem(name, method);
      }
    };

    Puis j'ouvre la même page dans plusieurs onglets, le résultat est quelque peu surprenant. Je vous mets les logs ci-dessous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // onglet 1
    Storage { length: 0 }
    set X // j'ajoute un élément à mon localStorage
    get X
    
    // onglet 2, 3, 4, 6
    get null
    Storage { length: 0 }
    get null
    
    // onglet 5
    get X
    Storage { X: "123456", length: 1 }
    get X
    Ainsi, lorsque j'ouvre des onglets supplémentaires (ici 5 autres onglets), certains ont bien '123456' dans le localStorage, et d'autres non. Pourtant, c'est bien la même URL, et le localStorage n'est pas modifié.

    Le handler est bien appelé lorsque le localStorage est modifié, et tous les onglets sont notifiés lorsqu'il y a une modification du localStorage.


    Encore plus marrant, en changeant le nom '123456' par autre chose, e.g., '456789', je vais retrouver à la fois '123456' et '45789' sur certains onglets, et pas sur d'autres. Parfois, en rajoutant un autre élément au localStorage au début de mon script, je vais le retrouver sur tous mes onglets mais toujours sans mes éléments '123456' et '45789'.
    J'avais alors essayé de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    let test = localStorage.getItem('x');
    if( test == null)
        test = 0;
    test++;
    localStorage.setItem('x', test);
    Et je me retrouvais avec plusieurs onglets ayant la même valeur pour x.


    À noter que j'ai testé mon code sur Firefox 58 et Firefox 59, et que mon code fait aussi d'autres choses, malheureusement, je ne peux pas en dévoiler le contenu (restrictions de mon employeur), et il m'est ainsi très difficile de vous présenter un code minimal reproduisant l'erreur.


    Mais j'ai comme l'impression que Firefox fait des "caches" des pages, faisant que je me retrouve avec un version de localStorage 'normale', ainsi qu'une version 'en cache'.


    Je pense pouvoir me dépatouiller en modifiant une variable bâteau de localStorage à l'ouverture de l'onglet, puis, avec les onglets ayant reçu l'event de modification de la variable bâteau, modifier la variable qui m'intéresse pour forcer sa mise à jour.

    Mais c'est quelque peu sale, et j'aimerais surtout savoir ce qu'il se passe actuellement avec mon code.



    Qu'en pensez-vous ?



    En vous remerciant d'avance pour votre aide,

  2. #2
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Billets dans le blog
    125
    Par défaut


    J'ai testé le code ci-dessous, sur 3 exemplaires de la page web ouverts en même temps, et sur la dernière version des navigateurs Chrome, Firefox et Edge sans constater aucun dysfonctionnement !

    Lorsque je clique sur le bouton "Changer la couleur" d'un exemplaire de la page, les deux autres exemplaires de la page reçoivent les informations correctes.

    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    <!DOCTYPE html>
    <html lang="fr" dir="ltr">
    <head>
    	<!-- cache-control avec max-age=60 pour le développement uniquement -->
      <meta http-equiv="cache-control" content="public, max-age=60">
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
      <meta name="author" content="Daniel Hagnoul">
    	<title>Test</title>
      <style>
                    *,
                    *:after,
                    *:before {
                            box-sizing: border-box;
                    }
                    
                    /* CSS du test */
     
     
                    /* Fin CSS du test */
     
      </style>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/locale/fr.js"></script>
    	<script src="http://danielhagnoul.developpez.com/lib/dvjh/dvjhUtilities-1.5.1.js"></script>
    	<script>
        'use strict';
                    
                    document.addEventListener( "DOMContentLoaded", ev => {
                            // le DOM est construit, la page web n'est pas visible
                            moment.locale( "fr" );
                            klog( `DOM ready   : ${ new kDvjhDate() }` );
                            
                            // code du test
                    
                            window.addEventListener( "storage", ev => {
                                    klog( "*** event storage ***")
                                    klog( "type : ", ev.type );
                                    klog( "timeStamp : ", ev.timeStamp );
                                    klog( "key : ", ev.key );
                                    klog( "oldValue : ", ev.oldValue );
                                    klog( "newValue : ", ev.newValue );
                            }, false );
                    
                            // fin code du test
                            
                    }, false );
        
        window.addEventListener( "load", ev => { 
                            // le DOM est construit et la page web est visible
                            klog( `Window load : ${ new kDvjhDate() }` );
                            
          // code du test
                            
                            const
                                    arCouleurs = [ "vert", "rouge", "bleu", "violet", "jaune", "magenta" ];
                            
                            k$( "#btnChanger" ).addEventListener( "click", ev => {
                                    klog( "*** btnChanger ***");
                                    klog( "in", localStorage.getItem( "couleur" ) );
                                    localStorage.setItem( "couleur", arCouleurs[ kIntRandom( 0, 5 ) ] );
                                    klog( "out", localStorage.getItem( "couleur" ) );
                            }, false );
     
                            // fin code du test
                            
          kIDUnique();
        }, false );
                    
                                    
      </script>
    </head>
    <body>
    	<main>
     
    		<button id="btnChanger">Changer la couleur</button>
     
    	</main>
    </body>
    </html>

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  3. #3
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Merci pour votre réponse.



    En effet, comme je l'ai indiqué dans mon premier message, lorsque je modifie le localStorage, je reçois bien les événements dans les autres onglets ouverts.

    Cependant si j'ouvre ensuite un autre onglet, cet onglet aura parfois un localStorage qui n'est pas à jour. Il y a un espèce de comportement indéterminé, parfois je peux ouvrir 10 onglets ayant tous un localStorage à jour, et d'autres fois, sur 10 onglets, je n'en aurais que 2 à jour.



    Après, j'utilise des bibliothèques externes qui font peut-être des choses bizarres. Ou peut-être une configuration "vie privée" de mon navigateur. Voire encore un truc magique du navigateur qui se produit dans certaines conditions. Le problème étant que je ne peux pas donner mon code pour le moment…

    Demain je vais essayer d'adapter ton code rapidement pour voir ce que cela me donne.
    Après, je ne peux malheureusement pas y passer trop de temps dessus, si je n'arrives pas à identifier la cause du problème, il faudra que je me contente d'une solution temporaire.

  4. #4
    Membre émérite
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 340
    Par défaut
    Bonsoir,
    J'ai fait un montage rapide de vos fragments de code : tout va bien sur Firefox, même pour le compteur "test".

    Un détail, dans votre sortie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Storage { X: "123456", length: 1 }
    Ce ne devrait pas être plutôt l'inverse ? 123456:"X"

    A noter qu'il y a dans Firefox un onglet "Stockage" qui permet de voir les données (il y a un même bouton de rafraîchissement).

    Après, j'utilise des bibliothèques externes qui font peut-être des choses bizarres.
    Si vous constatez avec un exemple simple que tout va bien, vous devriez ensuite bien réussir à simplifier progressivement votre projet jusqu'à garder l'essentiel et repérer ce qui cloche.

  5. #5
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par Loralina Voir le message
    Ce ne devrait pas être plutôt l'inverse ? 123456:"X"
    En effet, j'ai remplacé le nom des variables lorsque j'ai posté mon code, et j'ai fais une petite erreur à ce moment.

    Citation Envoyé par Loralina Voir le message
    Si vous constatez avec un exemple simple que tout va bien, vous devriez ensuite bien réussir à simplifier progressivement votre projet jusqu'à garder l'essentiel et repérer ce qui cloche.
    Je ne suis pas propriétaire des droits de diffusion de mon code, donc si je le faisais, je ne pourrais pas vous le montrer.
    De plus, j'ai aussi des contraintes de temps, si je n'arrive pas à résoudre le problème "rapidement", il faudra que je passe à autre chose.


    Heureusement, j'ai réussi à reproduire l'erreur avec un code très simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <script src='jquery.min.js'></script>
     
    <div id='print'>Not working</div>
    <script>
    $('#print').text( localStorage.getItem('Debug') );
    </script>
     
     
    <button type='button' id='btn'>Change value</button>
    <script>
    $( () => {
        $('#btn').click( () => {
            localStorage.setItem('Debug', 'Working');
        });
    });
    </script>
    J'ouvre un premier onglet, je clique sur le bouton.
    J'ouvre ensuite d'autres onglets jusqu'à ce que je ne voie pas apparaître "Working".


    Citation Envoyé par Loralina Voir le message
    A noter qu'il y a dans Firefox un onglet "Stockage" qui permet de voir les données (il y a un même bouton de rafraîchissement).
    En effet, et là j'ai l'impression que mon navigateur se fout de ma gueule...

    • onglet1 : 'Debug'
    • onglet2 : 'Debug' et '123456'
    • onglet3 : 'Debug'
    • onglet4 : rien


    Même en mettant à jour, rien ne change.


    Voici un code plus "complet":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <script src='jquery.min.js'></script>
     
    <script>let varname = 'Debug2';</script>
     
    <div id='print'>Not working</div>
    <script>
    $( () => {
        $('#print').text( localStorage.getItem(varname) );
    });
    </script>
     
     
    <button type='button' id='btn'>Change value</button>
    <script>
    $( () => {
     
        $(window).on('storage',function(e){
                console.log("MODIFIED !!!!!!!!"); 
                console.log(e);
        });
     
        $('#btn').click( () => {
            localStorage.setItem(varname, 'Working');
        });
    });
    </script>

    Je vous joins aussi le JQuery utilisé.
    Fichiers attachés Fichiers attachés

  6. #6
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Billets dans le blog
    125
    Par défaut
    Citation Envoyé par Neckara Voir le message
    [...] Heureusement, j'ai réussi à reproduire l'erreur avec un code très simple:
    Je viens de tester le code ci-dessous (votre code en Vanilla JS), 11 fois sur Chrome et 11 fois sur Firefox, et il n'y a pas d'erreur !

    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    <!DOCTYPE html>
    <html lang="fr" dir="ltr">
    <head>
    	<!-- cache-control avec max-age=60 pour le développement uniquement -->
      <meta http-equiv="cache-control" content="public, max-age=60">
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
      <meta name="author" content="Daniel Hagnoul">
    	<title>Test</title>
      <style>
                    *,
                    *:after,
                    *:before {
                            box-sizing: border-box;
                    }
                    
                    /* CSS du test */
     
     
                    /* Fin CSS du test */
     
      </style>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/locale/fr.js"></script>
    	<script src="http://danielhagnoul.developpez.com/lib/dvjh/dvjhUtilities-1.5.1.js"></script>
    	<script>
        'use strict';
                    
                    document.addEventListener( "DOMContentLoaded", ev => {
                            // le DOM est construit, la page web n'est pas visible
                            moment.locale( "fr" );
                            klog( `DOM ready   : ${ new kDvjhDate() }` );
                            
                            // code du test
                            
                            
                            
                            // fin code du test
                            
                    }, false );
        
        window.addEventListener( "load", ev => { 
                            // le DOM est construit et la page web est visible
                            klog( `Window load : ${ new kDvjhDate() }` );
                            
          // code du test
                            
                            k$( "#btn" ).addEventListener( "click", ev => {
                                    localStorage.setItem( "Debug", "Working" );
                            });
                                    
                            k$( "#print").textContent = localStorage.getItem( "Debug" );
                            
                            // fin code du test
                            
          kIDUnique();
        }, false );                 
      </script>
    </head>
    <body>
    	<main>
     
    		<div id="print">Not working</div>
    		<button id="btn">Change value</button>
     
    	</main>
    </body>
    </html>
    J'ai l'impression que la mémoire de votre localStorage est perturbée par vos nombreux tests plus ou moins réussis. Je vous conseille de faire le ménage avant de refaire un essai : localStorage.clear();

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  7. #7
    Membre émérite
    Femme Profil pro
    Autre
    Inscrit en
    Janvier 2017
    Messages
    340
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Janvier 2017
    Messages : 340
    Par défaut
    Bonjour,
    Je viens de repenser à ce que vous disiez ici :
    Citation Envoyé par Neckara Voir le message
    Ou peut-être une configuration "vie privée" de mon navigateur.
    Dans "about:preferences#privacy", "Accepter les cookies", "Les conserver jusqu'à", si je mets "La fermeture de Firefox", alors localStorage marche de façon totalement aléatoire.
    (A voir si c'est cette préférence à elle seule qui génère le problème ou s'il est lié à une combinaison de réglages.)

    Cela donne bien ce genre de choses :
    Ainsi, lorsque j'ouvre des onglets supplémentaires (ici 5 autres onglets), certains ont bien '123456' dans le localStorage, et d'autres non. Pourtant, c'est bien la même URL, et le localStorage n'est pas modifié.
    Le handler est bien appelé lorsque le localStorage est modifié, et tous les onglets sont notifiés lorsqu'il y a une modification du localStorage.

  8. #8
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Citation Envoyé par Loralina Voir le message
    Dans "about:preferences#privacy", "Accepter les cookies", "Les conserver jusqu'à", si je mets "La fermeture de Firefox", alors localStorage marche de façon totalement aléatoire.
    (A voir si c'est cette préférence à elle seule qui génère le problème ou s'il est lié à une combinaison de réglages.)
    Merci, j'ai en effet ce paramètre, je vais tester dès que possible.

    Est-ce que vous savez si une issue a été ouverte sur le bugtracker de Firefox, ou faut-il qu'on en ouvre une pour les avertir ?

  9. #9
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Par défaut
    J’ai trouvé celui-ci mais il semble seulement vaguement relié. Sinon, les autres titres de tickets que j’ai vus m’ont incité à te poser cette question : tu accèdes à tes fichiers en http: via un serveur local, ou bien en file: ?
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Supprimer une ligne ! Feuille a plusieurs onglets
    Par Danae123 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 11/07/2007, 10h55
  2. Macro exécutée sur plusieurs onglets
    Par Aizen64 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 05/06/2007, 09h59
  3. Export requete sur excel sur plusieur onglets
    Par Renardo dans le forum Access
    Réponses: 10
    Dernier message: 26/01/2007, 17h13
  4. Template d'application comportant plusieurs onglets
    Par g0ldenrno dans le forum Interfaces Graphiques en Java
    Réponses: 8
    Dernier message: 21/06/2006, 18h00
  5. [VBA-E] Impression page paire sur plusieurs onglets
    Par liop49 dans le forum Macros et VBA Excel
    Réponses: 23
    Dernier message: 17/02/2005, 15h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo