javascript - texto - Variables de página en script de contenido
modificar un label con javascript (6)
Creé un pequeño método de ayuda, diviértase :)
para recuperar las variables de la ventana "lannister", "always", "pays", "his", "deudas" , ejecuta lo siguiente:
var windowVariables = retrieveWindowVariables(["lannister", "always", "pays", "his", "debts"]);
console.log(windowVariables.lannister);
console.log(windowVariables.always);
mi código:
function retrieveWindowVariables(variables) {
var ret = {};
var scriptContent = "";
for (var i = 0; i < variables.length; i++) {
var currVariable = variables[i];
scriptContent += "if (typeof " + currVariable + " !== ''undefined'') $(''body'').attr(''tmp_" + currVariable + "'', " + currVariable + ");/n"
}
var script = document.createElement(''script'');
script.id = ''tmpScript'';
script.appendChild(document.createTextNode(scriptContent));
(document.body || document.head || document.documentElement).appendChild(script);
for (var i = 0; i < variables.length; i++) {
var currVariable = variables[i];
ret[currVariable] = $("body").attr("tmp_" + currVariable);
$("body").removeAttr("tmp_" + currVariable);
}
$("#tmpScript").remove();
return ret;
}
tenga en cuenta que utilicé jQuery ... puede usar fácilmente los js nativos "removeAttribute" y "removeChild" en su lugar.
¿Hay alguna forma de recuperar las variables de javascript de una página desde un script de contenido de Google Chrome?
No.
Los scripts de contenido se ejecutan en un entorno especial llamado mundo aislado. Tienen acceso al DOM de la página en la que se insertan, pero no a las variables o funciones de JavaScript creadas por la página. Mira a cada script de contenido como si no hubiera otro JavaScript ejecutándose en la página en la que se está ejecutando. Lo mismo ocurre a la inversa: JavaScript que se ejecuta en la página no puede invocar ninguna función ni acceder a ninguna variable definida por las secuencias de comandos de contenido.
Los mundos aislados permiten que cada script de contenido realice cambios en su entorno de JavaScript sin preocuparse por conflictos con la página o con otros scripts de contenido. Por ejemplo, un script de contenido podría incluir JQuery v1 y la página podría incluir JQuery v2, y no entrarían en conflicto entre sí.
Otro beneficio importante de los mundos aislados es que separan por completo el JavaScript de la página del JavaScript en extensiones. Esto nos permite ofrecer funcionalidad adicional a las secuencias de comandos de contenido que no deberían ser accesibles desde las páginas web sin preocuparse por las páginas web que acceden a ellas.
Realmente trabajé alrededor usando la API localStorge. Nota: para usar esto, nuestro contentscript debería poder leer localStorage. En el archivo manifest.json, simplemente agregue la cadena de "almacenamiento":
"permissions": [...,"storage"]
La función hijack vive en el script de contenido:
function hijack(callback) {
"use strict";
var code = function() {
//We have access to topframe - no longer a contentscript
var ourLocalStorageObject = {
globalVar: window.globalVar,
globalVar2: window.globalVar2
};
var dataString = JSON.stringify(ourLocalStorageObject);
localStorage.setItem("ourLocalStorageObject", dataString);
};
var script = document.createElement(''script'');
script.textContent = ''('' + code + '')()'';
(document.head||document.documentElement).appendChild(script);
script.parentNode.removeChild(script);
callback();
}
Ahora podemos llamar desde el contenido
document.addEventListener("DOMContentLoaded", function(event) {
hijack(callback);
});
o si usas jQuery en tu contenido, como yo:
$(document).ready(function() {
hijack(callback);
});
para extraer el contenido:
function callback() {
var localStorageString = localStorage.getItem("ourLocalStorageObject");
var ourLocalStorageObject= JSON.parse(localStorageString);
console.log("I can see now on content script", ourLocalStorageObject);
//(optional cleanup):
localStorage.removeItem("ourLocalStorageObject");
}
Esto se puede llamar varias veces, por lo que si su página cambia elementos o código interno, puede agregar detectores de eventos para actualizar su extensión con los nuevos datos.
Editar: he agregado devoluciones de llamada para que pueda estar seguro de que sus datos no serán inválidos (tuve este problema yo mismo)
Si sabe a qué variables desea acceder, puede crear un script de contenido personalizado rápido para recuperar sus valores.
En popup.js
:
chrome.tabs.executeScript(null, {code: ''var name = "property"''}, function() {
chrome.tabs.executeScript(null, {file: "retrieveValue.js"}, function(ret) {
for (var i = 0; i < ret.length; i++) {
console.log(ret[i]); //prints out each returned element in the array
}
});
});
En retrieveValue.js
:
function returnValues() {
return document.getElementById("element")[name];
//return any variables you need to retrieve
}
returnValues();
Puede modificar el código para devolver matrices u otros objetos.
Utilizando la solución de Liran, estoy agregando algo de corrección para Objects
, aquí está la solución correcta:
function retrieveWindowVariables(variables) {
var ret = {};
var scriptContent = "";
for (var i = 0; i < variables.length; i++) {
var currVariable = variables[i];
scriptContent += "if (typeof " + currVariable + " !== ''undefined'') $(''body'').attr(''tmp_" + currVariable + "'', JSON.stringify(" + currVariable + "));/n"
}
var script = document.createElement(''script'');
script.id = ''tmpScript'';
script.appendChild(document.createTextNode(scriptContent));
(document.body || document.head || document.documentElement).appendChild(script);
for (var i = 0; i < variables.length; i++) {
var currVariable = variables[i];
ret[currVariable] = $.parseJSON($("body").attr("tmp_" + currVariable));
$("body").removeAttr("tmp_" + currVariable);
}
$("#tmpScript").remove();
return ret;
}
Si realmente lo necesita, puede insertar un elemento <script>
en el DOM de la página; el código dentro de su elemento <script>
se ejecutará y ese código tendrá acceso a las variables de JavaScript en el alcance de la ventana. Luego, puede volver a comunicarlos al script de contenido utilizando atributos de data-
y disparando eventos personalizados.
¿Suena incómodo? Porqué sí, lo es, e intencionalmente, por todos los motivos en la documentación que el serg ha citado. Pero si realmente, realmente necesitas hacerlo, se puede hacer. Mira here y here para más información. ¡Y buena suerte!