C'è un modo per identificare in modo univoco un iframe in cui viene eseguito lo script di contenuto per l'estensione di Chrome?

Nella mia estensione di Chrome iniettilo lo script di contenuto in tutti gli IFRAMEs all'interno di una pagina. Ecco una parte del file manifest.json :

 "content_scripts": [ { "run_at": "document_end", "all_frames" : true, "match_about_blank": true, "matches": ["http://*/*", "https://*/*"], "js": ["content.js"] } ], 

Quindi una singola pagina web con più IFRAMEs finirà a eseguire molte copie del mio content.js iniettato. content.js .

La logica all'interno di content.js raccoglie i dati di each IFRAME cui viene iniettata o dalla pagina principale / superiore e lo invia allo script di background (utilizzando chrome.runtime.sendMessage ). Lo script di background deve a sua volta memorizzare i dati nella variabile globale, che viene successivamente utilizzata nell'estensione stessa.

Il problema che mi occuperò è che l'applicazione deve distinguere tra i "dati" ricevuti da più IFRAMEs , dal momento che il mio metodo di raccolta dati può essere richiamato ripetutamente all'interazione dell'utente con la pagina e quindi non posso semplicemente "scaricare" i dati ricevuti dallo script di background in un arrays. Devo invece usare un tipo di memory di tipo dictionary .

Posso sapere se i dati stanno provenienti da un IFRAME o dalla pagina superiore eseguendo quanto segue:

 //From the `content.js` var isIframe = window != window.top; 

e pensavo che se raccolgessi gli URL di pagina di each IFRAME dovrei essere in grado di utilizzarlo come chiave unica per memorizzare i dati nella variabile globale di tipo dictionary:

 //Again from content.js var strUniqueIFrameURL = document.URL; 

Beh, questo non funziona, perché due o più IFRAMEs possono avere gli stessi URL.

Quindi la mia domanda originale – come raccontare IFRAMEs nella pagina separata? C'è qualche ID univoco o somethign che Chrome assegna a loro?

È ansible identificare il relativo posto del documento nella gerarchia di iframes. A seconda della struttura della pagina, questo può risolvere il problema.

La tua estensione è in grado di accedere a window.parent e ai suoi frame. Questo dovrebbe funzionare, o alless funziona per me in un caso di prova:

 // Returns the index of the iframe in the parent document, // or -1 if we are the topmost document function iframeIndex(win) { win = win || window; // Assume self by default if (win.parent != win) { for (var i = 0; i < win.parent.frames.length; i++) { if (win.parent.frames[i] == win) { return i; } } throw Error("In a frame, but could not find myself"); } else { return -1; } } 

Puoi modificarla per sostenere gli iframes di nidificazione, ma il principio dovrebbe funzionare.

Io stavo prendendo per farlo io stesso, così vai qui:

 // Returns a unique index in iframe hierarchy, or empty string if topmost function iframeFullIndex(win) { win = win || window; // Assume self by default if (iframeIndex(win) < 0) { return ""; } else { return iframeFullIndex(win.parent) + "." + iframeIndex(win); } } 

Proprio per espandere la risposta di @ Xan, ecco il mio metodo per get un indice di IFRAME considerando il suo ansible nidificazione all'interno di altri IFRAMEs . Utilizzo la notazione forward-iframe, il che significa che l'indice principale IFRAME sarà dato innanzitutto, seguiti da indici di figlio, ecc. Inoltre, per evitare una ansible confusione con numbers a virgola mobile, utilizzerò il sottolineatura per un separatore anziché il punto.

Quindi, per rispondere alla mia domanda originale, una volta che ho l'indice IFRAME all'interno della pagina, l'identificerò in quella pagina (associato all'URL di IFRAME ).

Ecco il codice per ottenerlo:

 function iframeIndex(wnd) { //RETURN: // = "" for top window // = IFrame zero-based index with nesting, example: "2", or "0_4" // = "?" if error return _iframeIndex(wnd || window); // Assume self by default } function _iframeIndex(wnd) { var resInd = ""; var wndTop = window.top; if(wnd == wndTop) return resInd; var wndPar = wnd.parent; if(wndPar != wndTop) { resInd = _iframeIndex(wndPar) + "_"; } var frmsPar = wndPar.frames; for(var i = 0; i < frmsPar.length; i++) { if(frmsPar[i] == wnd) return resInd + i; } return resInd + "?"; } 

È ansible generare un id pseudo-unico utilizzando una combinazione di timestamp e un numero random each volta che viene caricato uno script di contenuto, come questo:

 var psUid = (new Date()).getTime() + '_' + Math.random(); 

E poi submit tutti i tuoi messaggi relativi ai dati sullo background con questo ID.