9
votes

ID unique persistant pour les onglets chromés qui dure entre les sessions de navigateur

J'essaie de déterminer un moyen d'établir un identifiant unique pour les onglets chromés répondant aux conditions suivantes:

  • identifie de manière unique chaque onglet
  • reste la même chose pour un onglet donné entre les redémarrages du navigateur (onglets restaurés de session)
  • reste le même si un onglet est fermé puis rouvert avec un onglet fermé d'annulation (Ctrl + Shift + T)
  • reste distinct si un onglet est dupliqué

    J'ai fait des recherches plutôt agressives pour trouver une solution globale, mais rien ne semble tout à fait le tour. Voici les méthodes que j'ai essayées, dans l'ordre croissant d'efficacité:

    • UTILISER AVEC UNE TAB.ID: Ne persiste pas entre les sessions de navigateur ni près / Fermer-Fermer
    • Mettez un GUID dans les cookies: n'est pas unique par onglet, uniquement par domaine / URL
    • Mettez un GUIG en localStorage: persiste entre des sessions de navigateur et de fermer / d'annuler, mais n'est pas unique par onglet, uniquement par domaine
    • Mettez un GUID dans la sessionStorage: unique par onglet, persiste à proximité / d'annulation - proche, unique pour les onglets dupliqués, mais est essuyé entre les sessions de navigateur
    • Utilisez des attributs de document WebPage identifiables comme une clé unique: C'est la meilleure approche que j'ai trouvée jusqu'à présent. Une clé peut être construite via un script de contenu à partir des valeurs suivantes: [emplacement.href, document.referrer, historique.length] . .

      Concernant cette dernière approche, la clé construite est unique dans tous les onglets qui partagent une URL commun, un référent et une longueur d'historique. Ces valeurs resteront les mêmes pour un onglet donné entre les redémarrages du navigateur / session-restaure et fermer / se ferme. Bien que cette clé est "jolie" unique, il existe des cas où il est ambigu: par exemple, 3 nouveaux onglets ouverts à http: // www.google.com aurait tous la même clé en commun (et ce genre de chose se passe assez souvent dans la pratique).

      Le «GUID GUID dans la session de sessionStorage» peut également être utilisé pour désambiguez entre plusieurs onglets avec la même clé construite pour les cas de fermeture / des onglets de fermeture et de double tablication lors de la session de navigateur actuelle. Mais cela ne résout pas le problème de l'ambiguïté entre les redémarrages du navigateur.

      Cette dernière ambiguïtée peut être partiellement atténée lors de la restauration de la session en observant quels onglets chrome s'ouvrent ensemble dans quelles fenêtres et extrapolantes pour une clé ambiguë donnée qui appartient à la fenêtre basée sur la présence d'onglets «frères de frères» (enregistrés pendant la session de navigateur précédente). Comme vous pouvez l'imaginer, la mise en œuvre de cette solution est tout à fait impliquée et plutôt mangée. Et il ne peut que désambigucher entre des onglets identiques que Chrome se redonne à différentes fenêtres. Qui laisse des onglets identiques qui se retrouvent dans la même fenêtre que de manière irréconciliblement ambiguë.

      Y a-t-il une meilleure façon? Guid Guide par onglet unique, généré par navigateur, qui persiste entre les redémarrages du navigateur (restaurations de session) et fermer / se fermer serait idéal mais jusqu'à présent, je n'ai rien trouvé de tel.


0 commentaires

3 Réponses :


1
votes

Si je comprends correctement votre problème, votre 5ème méthode devrait faire l'affaire, mais avec ces deux critères:

  • chrome.tabs.windowid (ID de la fenêtre L'onglet est contenu dans)
  • chrome.tabs.index (l'index basé sur zéro de l'onglet dans sa fenêtre)

    Toutes ces valeurs doivent être stockées dans votre extension. En plus de cela, vous devrez également connecter votre poste à chrome.tabs.onupdated () et mis à jour en conséquence, lorsque des onglets sont déplacés, déplacés sur les fenêtres du propriétaire, etc.


5 commentaires

Bonnes idées. Malheureusement, les changements de fenêtres entre les sessions de navigateur, mais si je peux déduire des changements de fenêtres entre les sessions en vous souvenant et en comparant quels onglets se trouvent dans chaque fenêtre avant et après un redémarrage du navigateur, je devrais pouvoir utiliser .index comme vous le suggère de désagréger deux onglets autrement identiques dans une fenêtre donnée. Merci beaucoup.


J'ajouterai que je devrais être capable de corréler un "avant-redémarrage" rappelé windowid avec une fenêtre ouverte "après-redémarrage", si je peux identifier n'importe quel onglet Single un seul référent URL + + Touche de longueur d'histoire. Depuis que ladite onglet est le seul avec cette clé particulière, je sais quelle fenêtre il appartient; Je sais donc que tous les onglets rappelés avec le même "ancien" Windowid appartiennent également à la même "nouvelle" fenêtre.


@Joelpt Oui, Windowid n'est pas fiable, mais si vous connectez chrome.window.onCréé et chrome.window.onremoved Événements Vous pouvez facilement imiter un index (identifiant de commande) sur toutes les fenêtres.


Les fenêtres sont-elles énumérées dans le même ordre entre les redémarrages du navigateur?


@Genegolovchinsky Test & VOIR. Normalement, il devrait



4
votes

La question ici fait la plupart des travaux de découverte et la réponse acceptée le complète essentiellement, mais il y a un grand écart de mise en œuvre toujours pour que les personnes cherchent à mettre en œuvre quelque chose qui nécessite des identifiants persistants. J'ai tenté de distiller cela dans une mise en œuvre réelle.

à recap: les onglets peuvent être (presque) identifiés de manière unique et systématiquement comme requis par la question en maintenant un registre des onglets qui stocke la combinaison de variables suivante dans le stockage persistant local:

  • onglet.id
  • onglet.index
  • une "empreinte digitale" du document ouvert dans l'onglet - [emplacement.href, document.referrer, historique.length]

    Ces variables peuvent être suivies et stockées dans le registre à l'aide des auditeurs sur une combinaison des événements suivants:

    • ONUPDATED
    • OnCréated
    • onMoved
    • Ondatetached
    • Onatcheched
    • onremoved
    • ONERPLACÉD

      Il existe toujours des moyens de tromper cette méthode, mais dans la pratique, ils sont probablement assez rares - surtout des cas de bord.

      Comme on dirait que je ne suis pas le seul à avoir besoin de résoudre ce problème, j'ai construit ma mise en œuvre en tant que bibliothèque avec l'intention de pouvoir être utilisée dans une extension chromée. Il est compatible avec licence et disponible sur GitHub pour les demandes de forking et de tirage (en fait, tout retour être les bienvenus - il y a définitivement des améliorations possibles).


0 commentaires

1
votes

Mettez ceci comme un script de fond persistant dans Manifest.json: XXX PRE>

Voici de fond.js. Espérons que le code est explicite auto-explicite. P>

var tabs_hashes = {};
var tabs_hashes_save_queued = false;

function Start(){
    chrome.tabs.query({windowType: "normal"}, function(querytabs){
        querytabs.forEach(function(tab){
            tabs_hashes[tab.id] = GetHash(tab.url);
        });

        if (localStorage.getItem("tabs_hashes") !== null){

            var ref_load = JSON.parse(localStorage["tabs_hashes"]);
            var ref_tabId = {};


            querytabs.forEach(function(tab){
                for (var t = 0; t < ref_load.length; t++){
                    if (ref_load[t][1] === tabs_hashes[tab.id]){
                        ref_tabId[ref_load[t][0]] = tab.id;
                        ref_load.splice(t, 1);
                        break;
                    }
                }
            });

            // do what you have to do to convert previous tabId to the new one
            // just use ref_tabId[your_previous_tabId] to get the current corresponding new tabId
            console.log(ref_tabId);

        }
    });
}


function SaveHashes(){
    if (!tabs_hashes_save_queued && Object.keys(tabs_hashes).length > 0){
        tabs_hashes_save_queued = true;
        chrome.tabs.query({windowType: "normal"}, function(querytabs){
            var data = [];
            querytabs.forEach(function(tab){
                if (tabs_hashes[tab.id]){
                    data.push([tab.id, tabs_hashes[tab.id]]);
                } else {
                    data.push([tab.id, GetHash(tab.url)]);
                }
            });
            localStorage["tabs_hashes"] = JSON.stringify(data);
            setTimeout(function(){ tabs_hashes_save_queued = false; }, 1000);
        });
    }
}

function GetHash(s){
    var hash = 0;
    if (s.length === 0){
        return 0;
    }
    for (var i = 0; i < s.length; i++){
        hash = (hash << 5)-hash;
        hash = hash+s.charCodeAt(i);
        hash |= 0;
    }
    return Math.abs(hash);
}


chrome.tabs.onCreated.addListener(function(tab){
    SaveHashes();
});
chrome.tabs.onAttached.addListener(function(tabId){
    SaveHashes();
});
chrome.tabs.onRemoved.addListener(function(tabId){
    delete tabs_hashes[tabId];
    SaveHashes();
});
chrome.tabs.onDetached.addListener(function(tabId){
    SaveHashes();
});
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo){
    if (changeInfo.pinned != undefined || changeInfo.url != undefined){
        delete tabs_hashes[tabId];
        SaveHashes();
    }
});
chrome.tabs.onMoved.addListener(function(tabId){
    SaveHashes();
});
chrome.tabs.onReplaced.addListener(function(addedTabId, removedTabId){
    delete tabs_hashes[removedTabId];
    SaveHashes();
});


Start();


0 commentaires