Reinyección del script de contenido de extensión de Chrome después de la actualización o instalación


Después de instalar o actualizar la extensión de Chrome en la que estoy trabajando, los scripts de contenido (especificados en el manifiesto) no se reinyectan, por lo que se requiere una actualización de página para que la extensión funcione. ¿Hay alguna manera de forzar que los scripts sean inyectados de nuevo?

Creo que podría inyectarlos de nuevo programáticamente eliminándolos del manifiesto y luego manejando qué páginas inyectar en la página de fondo, pero esta no es una buena solución.

No quiero automáticamente actualice las pestañas del usuario porque eso podría perder algunos de sus datos. Safari actualiza automáticamente todas las páginas cuando instala o actualiza una extensión.

Author: pb2q, 2012-06-12

3 answers

Hay una manera de permitir que una extensión de script de contenido pesado continúe funcionando después de una actualización, y para que funcione inmediatamente después de la instalación.

Instalar

El método de instalación es simplemente iterar a través de todas las pestañas en todas las ventanas, e inyectar algunos scripts mediante programación en pestañas con URLs coincidentes.

Obviamente, tienes que hacerlo en un script background page o event page declarado en manifestar.json:

"background": {
    "scripts": ["background.js"]
},

Background.js:

// Add a `manifest` property to the `chrome` object.
chrome.manifest = chrome.app.getDetails();

var injectIntoTab = function (tab) {
    // You could iterate through the content scripts here
    var scripts = chrome.manifest.content_scripts[0].js;
    var i = 0, s = scripts.length;
    for( ; i < s; i++ ) {
        chrome.tabs.executeScript(tab.id, {
            file: scripts[i]
        });
    }
}

// Get all windows
chrome.windows.getAll({
    populate: true
}, function (windows) {
    var i = 0, w = windows.length, currentWindow;
    for( ; i < w; i++ ) {
        currentWindow = windows[i];
        var j = 0, t = currentWindow.tabs.length, currentTab;
        for( ; j < t; j++ ) {
            currentTab = currentWindow.tabs[j];
            // Skip chrome:// and https:// pages
            if( ! currentTab.url.match(/(chrome|https):\/\//gi) ) {
                injectIntoTab(currentTab);
            }
        }
    }
});

Actualizar

El método de actualización se basa en el hecho de que los scripts de contenido se dejan inyectados después de que una extensión se deshabilita, desinstala o actualiza.

Cuando se realiza la conexión de puerto, se agrega un manejador onDisconnect. Esto espera un segundo después del evento de desconexión y luego intenta volver a conectarse. Si falla, se dispara otro onDisconnect para que el proceso vuelva a ocurrir, hasta que se realice una conexión. No es perfecto, pero funciona.

El script de contenido:

var port;

// Attempt to reconnect
var reconnectToExtension = function () {
    // Reset port
    port = null;
    // Attempt to reconnect after 1 second
    setTimeout(connectToExtension, 1000 * 1);
};

// Attempt to connect
var connectToExtension = function () {

    // Make the connection
    port = chrome.runtime.connect({name: "my-port"});

    // When extension is upgraded or disabled and renabled, the content scripts
    // will still be injected, so we have to reconnect them.
    // We listen for an onDisconnect event, and then wait for a second before
    // trying to connect again. Becuase chrome.runtime.connect fires an onDisconnect
    // event if it does not connect, an unsuccessful connection should trigger
    // another attempt, 1 second later.
    port.onDisconnect.addListener(reconnectToExtension);

};

// Connect for the first time
connectToExtension();
 26
Author: Tom Ashworth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-11 22:32:51

La única manera de forzar que se inyecte un script de contenido sin actualizar la página es mediante inyección programática.

Puede obtener todas las pestañas e inyectar código en ellas utilizando la API chrome tabs. Por ejemplo, puede almacenar una versión del manifiesto en el almacenamiento local y cada vez comprobar si la versión del manifiesto es antigua( en la página de fondo), si es así, puede obtener todas las pestañas activas e inyectar su código mediante programación, o cualquier otra solución que le actualizar.

Obtenga todas las pestañas usando:
chrome.pestañas.consulta

E inyecta tu código en todas las páginas
chrome.tabs.executeScript(tabId, {file: "content_script.js"});

 19
Author: saroyanm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-30 11:49:44

¿No puedes agregar ?ver=2.10 al final de css o js que actualizaste?

"content_scripts": [ {
      "css": [ "css/cs.css?ver=2.10" ],
      "js": [ "js/contentScript.js?ver=2.10" ],
      "matches": [ "http://*/*", "https://*/*" ],
      "run_at": "document_end"
   } ],
 -6
Author: Alireza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-31 17:34:06