chrome.scripting (original) (raw)

Descripción

Usa la API de chrome.scripting para ejecutar la secuencia de comandos en diferentes contextos.

Permisos

scripting

Disponibilidad

Chrome 88 y versiones posterioresMV3 y versiones posteriores

Manifiesto

Para usar la API de chrome.scripting, declara el permiso "scripting" en el manifiesto, además de los permisos de host para las páginas en las que se insertarán los secuencias de comandos. Usa la clave "host_permissions" o el permiso "activeTab", que otorgan permisos de host temporales. En el siguiente ejemplo, se usa el permiso activeTab.

{
  "name": "Scripting Extension",
  "manifest_version": 3,
  "permissions": ["scripting", "activeTab"],
  ...
}

Conceptos y uso

Puedes usar la API de chrome.scripting para insertar JavaScript y CSS en sitios web. Esto es similar a lo que puedes hacer con las secuencias de comandos de contenido. Sin embargo, si usas el espacio de nombres chrome.scripting, las extensiones pueden tomar decisiones durante el tiempo de ejecución.

Objetivos de inserción

Puedes usar el parámetro target para especificar un destino en el que se insertará JavaScript o CSS.

El único campo obligatorio es tabId. De forma predeterminada, una inyección se ejecutará en el marco principal de la pestaña especificada.

function getTabId() { ... }

chrome.scripting
    .executeScript({
      target : {tabId : getTabId()},
      files : [ "script.js" ],
    })
    .then(() => console.log("script injected"));

Para ejecutar en todos los fotogramas de la pestaña especificada, puedes establecer el valor booleano allFrames en true.

function getTabId() { ... }

chrome.scripting
    .executeScript({
      target : {tabId : getTabId(), allFrames : true},
      files : [ "script.js" ],
    })
    .then(() => console.log("script injected in all frames"));

También puedes insertar código en marcos específicos de una pestaña si especificas IDs de marcos individuales. Para obtener más información sobre los IDs de fotogramas, consulta la API de chrome.webNavigation.

function getTabId() { ... }

chrome.scripting
    .executeScript({
      target : {tabId : getTabId(), frameIds : [ frameId1, frameId2 ]},
      files : [ "script.js" ],
    })
    .then(() => console.log("script injected on target frames"));

Código insertado

Las extensiones pueden especificar el código que se insertará a través de un archivo externo o una variable de tiempo de ejecución.

Archivos

Los archivos se especifican como cadenas que son rutas relativas al directorio raíz de la extensión. El siguiente código insertará el archivo script.js en el marco principal de la pestaña.

function getTabId() { ... }

chrome.scripting
    .executeScript({
      target : {tabId : getTabId()},
      files : [ "script.js" ],
    })
    .then(() => console.log("injected script file"));

Funciones de tiempo de ejecución

Cuando insertas JavaScript con scripting.executeScript(), puedes especificar una función para que se ejecute en lugar de un archivo. Esta función debe ser una variable de función disponible para el contexto de extensión actual.

function getTabId() { ... }
function getTitle() { return document.title; }

chrome.scripting
    .executeScript({
      target : {tabId : getTabId()},
      func : getTitle,
    })
    .then(() => console.log("injected a function"));
function getTabId() { ... }
function getUserColor() { ... }

function changeBackgroundColor() {
  document.body.style.backgroundColor = getUserColor();
}

chrome.scripting
    .executeScript({
      target : {tabId : getTabId()},
      func : changeBackgroundColor,
    })
    .then(() => console.log("injected a function"));

Para solucionar este problema, usa la propiedad args:

function getTabId() { ... }
function getUserColor() { ... }
function changeBackgroundColor(backgroundColor) {
  document.body.style.backgroundColor = backgroundColor;
}

chrome.scripting
    .executeScript({
      target : {tabId : getTabId()},
      func : changeBackgroundColor,
      args : [ getUserColor() ],
    })
    .then(() => console.log("injected a function"));

Cadenas de entorno de ejecución

Si insertas CSS en una página, también puedes especificar una cadena para usar en la propiedad css. Esta opción solo está disponible para scripting.insertCSS(). No puedes ejecutar una cadena con scripting.executeScript().

function getTabId() { ... }
const css = "body { background-color: red; }";

chrome.scripting
    .insertCSS({
      target : {tabId : getTabId()},
      css : css,
    })
    .then(() => console.log("CSS injected"));

Cómo controlar los resultados

Los resultados de la ejecución de JavaScript se pasan a la extensión. Se incluye un solo resultado por fotograma. Se garantiza que el fotograma principal será el primer índice del array resultante. Todos los demás fotogramas se encuentran en un orden no determinístico.

function getTabId() { ... }
function getTitle() { return document.title; }

chrome.scripting
    .executeScript({
      target : {tabId : getTabId(), allFrames : true},
      func : getTitle,
    })
    .then(injectionResults => {
      for (const {frameId, result} of injectionResults) {
        console.log(`Frame ${frameId} result:`, result);
      }
    });

scripting.insertCSS() no devuelve ningún resultado.

Promesas

Si el valor resultante de la ejecución del script es una promesa, Chrome esperará a que se resuelva y devolverá el valor resultante.

function getTabId() { ... }
async function addIframe() {
  const iframe = document.createElement("iframe");
  const loadComplete =
      new Promise(resolve => iframe.addEventListener("load", resolve));
  iframe.src = "https://example.com";
  document.body.appendChild(iframe);
  await loadComplete;
  return iframe.contentWindow.document.title;
}

chrome.scripting
    .executeScript({
      target : {tabId : getTabId(), allFrames : true},
      func : addIframe,
    })
    .then(injectionResults => {
      for (const frameResult of injectionResults) {
        const {frameId, result} = frameResult;
        console.log(`Frame ${frameId} result:`, result);
      }
    });

Ejemplos

Anula el registro de todas las secuencias de comandos de contenido dinámico

El siguiente fragmento contiene una función que anula el registro de todos los secuencias de comandos de contenido dinámico que la extensión haya registrado anteriormente.

async function unregisterAllDynamicContentScripts() {
  try {
    const scripts = await chrome.scripting.getRegisteredContentScripts();
    const scriptIds = scripts.map(script => script.id);
    return chrome.scripting.unregisterContentScripts({ ids: scriptIds });
  } catch (error) {
    const message = [
      "An unexpected error occurred while",
      "unregistering dynamic content scripts.",
    ].join(" ");
    throw new Error(message, {cause : error});
  }
}

Para probar la API de chrome.scripting, instala el ejemplo de secuencias de comandos del repositorio de ejemplos de extensiones de Chrome.

Tipos

ContentScriptFilter

Chrome 96 y versiones posteriores

Propiedades

CSSInjection

Propiedades

ExecutionWorld

Chrome 95 y versiones posteriores

Es el entorno de JavaScript en el que se ejecutará un script.

Enum

"ISOLATED"
Especifica el mundo aislado, que es el entorno de ejecución único para esta extensión.

"MAIN"
Especifica el mundo principal del DOM, que es el entorno de ejecución compartido con el JavaScript de la página host.

InjectionResult

Propiedades

InjectionTarget

Propiedades

RegisteredContentScript

Chrome 96 y versiones posteriores

Propiedades

ScriptInjection

Propiedades

Enum

Métodos

executeScript()

chrome.scripting.executeScript(
  injection: ScriptInjection,
): Promise<InjectionResult[]>

Inserta una secuencia de comandos en un contexto de destino. De forma predeterminada, la secuencia de comandos se ejecutará en document_idle o de inmediato si la página ya se cargó. Si se establece la propiedad injectImmediately, la secuencia de comandos se insertará sin esperar, incluso si la página no terminó de cargarse. Si la secuencia de comandos se evalúa como una promesa, el navegador esperará a que se resuelva la promesa y devolverá el valor resultante.

Parámetros

Muestra

getRegisteredContentScripts()

Chrome 96 y versiones posteriores

chrome.scripting.getRegisteredContentScripts(
  filter?: ContentScriptFilter,
): Promise<RegisteredContentScript[]>

Devuelve todas las secuencias de comandos de contenido registradas de forma dinámica para esta extensión que coinciden con el filtro determinado.

Parámetros

Muestra

insertCSS()

chrome.scripting.insertCSS(
  injection: CSSInjection,
): Promise

Inserta una hoja de diseño CSS en un contexto de destino. Si se especifican varios fotogramas, se ignoran las inserciones que no se realicen correctamente.

Parámetros

Muestra

registerContentScripts()

Chrome 96 y versiones posteriores

chrome.scripting.registerContentScripts(
  scripts: RegisteredContentScript[],
): Promise

Registra una o más secuencias de comandos de contenido para esta extensión.

Parámetros

Muestra

removeCSS()

Chrome 90 y versiones posteriores

chrome.scripting.removeCSS(
  injection: CSSInjection,
): Promise

Quita una hoja de estilo CSS que esta extensión insertó previamente en un contexto de destino.

Parámetros

Muestra

unregisterContentScripts()

Chrome 96 y versiones posteriores

chrome.scripting.unregisterContentScripts(
  filter?: ContentScriptFilter,
): Promise

Anula el registro de las secuencias de comandos de contenido de esta extensión.

Parámetros

Muestra

updateContentScripts()

Chrome 96 y versiones posteriores

chrome.scripting.updateContentScripts(
  scripts: RegisteredContentScript[],
): Promise

Actualiza uno o más secuencias de comandos de contenido para esta extensión.

Parámetros

Muestra