хром.скриптинг

Описание

Используйте API chrome.scripting для выполнения скриптов в различных контекстах.

Разрешения

scripting

Доступность

Chrome 88+ MV3+

Манифест

Чтобы использовать API chrome.scripting , объявите разрешение "scripting" в манифесте , а также разрешения хоста для страниц, в которые будут внедряться скрипты. Используйте ключ "host_permissions" или разрешение "activeTab" , которое предоставляет временные разрешения хоста. В следующем примере используется разрешение «activeTab».

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

Концепции и использование

API chrome.scripting можно использовать для внедрения JavaScript и CSS на веб-сайты. Это похоже на то, что можно делать со скриптами контента . Однако, используя пространство имён chrome.scripting , расширения могут принимать решения во время выполнения.

Цели инъекций

Вы можете использовать параметр target , чтобы указать цель, в которую следует внедрить JavaScript или CSS.

Единственное обязательное поле — tabId . По умолчанию инъекция будет выполнена в главном фрейме указанной вкладки.

function getTabId() { ... }

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

Для запуска во всех кадрах указанной вкладки можно установить логическое значение allFrames в true .

function getTabId() { ... }

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

Вы также можете внедрять контент в определённые фреймы вкладки, указав их идентификаторы. Подробнее об идентификаторах фреймов см. в API chrome.webNavigation .

function getTabId() { ... }

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

Внедренный код

Расширения могут указывать код, который будет внедрен, либо через внешний файл, либо через переменную времени выполнения.

Файлы

Файлы указываются в виде строк, которые являются путями относительно корневого каталога расширения. Следующий код добавит файл script.js в главный фрейм вкладки.

function getTabId() { ... }

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

Функции времени выполнения

При внедрении JavaScript с помощью scripting.executeScript() вы можете указать функцию, которая будет выполнена вместо файла. Эта функция должна быть функциональной переменной, доступной текущему контексту расширения.

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"));

Эту проблему можно обойти, используя свойство 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"));

Строки времени выполнения

При внедрении CSS на страницу вы также можете указать строку для использования в свойстве css . Эта возможность доступна только для scripting.insertCSS() ; выполнить строку с помощью scripting.executeScript() невозможно.

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

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

Обрабатывайте результаты

Результаты выполнения JavaScript передаются в расширение. Для каждого кадра добавляется один результат. Основной кадр гарантированно является первым индексом в результирующем массиве; все остальные кадры располагаются в неопределённом порядке.

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() не возвращает никаких результатов.

Обещания

Если результирующее значение выполнения скрипта является обещанием, Chrome дождется завершения обещания и вернет результирующее значение.

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);
      }
    });

Примеры

Отменить регистрацию всех скриптов динамического контента

Следующий фрагмент содержит функцию, которая отменяет регистрацию всех скриптов динамического содержимого, которые расширение ранее зарегистрировало.

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});
  }
}

Чтобы опробовать API chrome.scripting , установите пример скрипта из репозитория примеров расширений Chrome .

Типы

ContentScriptFilter

Хром 96+

Характеристики

  • идентификаторы

    строка[] необязательная

    Если указано, getRegisteredContentScripts вернет только скрипты с идентификатором, указанным в этом списке.

CSSInjection

Характеристики

  • css

    строка необязательная

    Строка, содержащая CSS-код для внедрения. Необходимо указать только один из files и css .

  • файлы

    строка[] необязательная

    Путь к CSS-файлам для внедрения относительно корневого каталога расширения. Необходимо указать только один из files и css .

  • источник

    StyleOrigin необязательно

    Источник стиля для инъекции. По умолчанию — 'AUTHOR' .

  • Подробная информация, указывающая цель, в которую следует вставить CSS.

ExecutionWorld

Хром 95+

Мир JavaScript для выполнения скрипта.

Перечисление

«ИЗОЛИРОВАННЫЙ»
Указывает изолированный мир, который является средой выполнения, уникальной для этого расширения.

"ОСНОВНОЙ"
Указывает основной мир DOM, который представляет собой среду выполнения, используемую совместно с JavaScript-кодом страницы хоста.

InjectionResult

Характеристики

  • documentId

    нить

    Хром 106+

    Документ, связанный с инъекцией.

  • frameId

    число

    Хром 90+

    Кадр, связанный с инъекцией.

  • результат

    любой необязательный

    Результат выполнения скрипта.

InjectionTarget

Характеристики

  • allFrames

    логическое необязательное

    Должен ли скрипт внедряться во все фреймы вкладки. Значение по умолчанию — false. Значение не должно быть true, если указан параметр frameIds .

  • идентификаторы документов

    строка[] необязательная

    Хром 106+

    Идентификаторы конкретных documentIds для внедрения. Этот параметр не должен быть задан, если задан frameIds .

  • frameIds

    номер[] необязательно

    Идентификаторы конкретных кадров для внедрения.

  • tabId

    число

    Идентификатор вкладки, в которую следует выполнить инъекцию.

RegisteredContentScript

Хром 96+

Характеристики

  • allFrames

    логическое необязательное

    Если указано значение true, вставка будет выполнена во все фреймы, даже если фрейм не является самым верхним во вкладке. Каждый фрейм проверяется независимо на соответствие требованиям URL; вставка не будет выполнена в дочерние фреймы, если требования URL не выполнены. Значение по умолчанию — false, что означает, что сопоставляется только верхний фрейм.

  • css

    строка[] необязательная

    Список CSS-файлов для внедрения на соответствующие страницы. Они внедряются в том порядке, в котором они указаны в этом массиве, до построения или отображения DOM-модели страницы.

  • исключить совпадения

    строка[] необязательная

    Исключает страницы, в которые этот скрипт контента в противном случае был бы внедрён. Подробнее о синтаксисе этих строк см. в разделе «Шаблоны соответствия» .

  • идентификатор

    нить

    Идентификатор скрипта контента, указанный в вызове API. Не должен начинаться с символа «_», так как он зарезервирован в качестве префикса для генерируемых идентификаторов скриптов.

  • js

    строка[] необязательная

    Список файлов JavaScript для внедрения на соответствующие страницы. Они внедряются в том порядке, в котором они указаны в этом массиве.

  • matchOriginAsFallback

    логическое необязательное

    Хром 119+

    Указывает, можно ли внедрить скрипт во фреймы, URL-адрес которых содержит неподдерживаемую схему, в частности: about:, data:, blob: или filesystem:. В этих случаях проверяется источник URL-адреса, чтобы определить, следует ли внедрять скрипт. Если источник равен null (как в случае URL-адресов data:), то используемым источником будет либо фрейм, создавший текущий фрейм, либо фрейм, инициировавший навигацию к этому фрейму. Обратите внимание, что это может быть не родительский фрейм.

  • спички

    строка[] необязательная

    Указывает, на какие страницы будет внедрен этот скрипт контента. Подробнее о синтаксисе этих строк см. в разделе «Шаблоны соответствия» . Необходимо указать для registerContentScripts .

  • persistAcrossSessions

    логическое необязательное

    Указывает, будет ли этот скрипт контента сохраняться в будущих сеансах. Значение по умолчанию — true.

  • runAt

    RunAt необязательно

    Указывает, когда файлы JavaScript внедряются в веб-страницу. Предпочтительное значение по умолчанию — document_idle .

  • мир

    ExecutionWorld необязательно

    Хром 102+

    «Мир» JavaScript, в котором будет запускаться скрипт. По умолчанию — ISOLATED .

ScriptInjection

Характеристики

  • аргументы

    любой[] необязательный

    Хром 92+

    Аргументы, передаваемые в указанную функцию. Это допустимо только при указании параметра func . Эти аргументы должны быть сериализуемы в формате JSON.

  • файлы

    строка[] необязательная

    Путь к JS- или CSS-файлам для внедрения относительно корневого каталога расширения. Необходимо указать только один из files или func .

  • вводить немедленно

    логическое необязательное

    Хром 102+

    Следует ли как можно скорее запустить инъекцию в целевой объект. Обратите внимание, что это не гарантирует, что инъекция произойдёт до загрузки страницы, поскольку страница может быть уже загружена к моменту, когда скрипт достигнет целевой страницы.

  • цель

    Подробности, указывающие цель, в которую следует внедрить скрипт.

  • мир

    ExecutionWorld необязательно

    Хром 95+

    «Мир» JavaScript, в котором будет запускаться скрипт. По умолчанию — ISOLATED .

  • функция

    необязательный

    Хром 92+

    Функция JavaScript для внедрения. Эта функция будет сериализована, а затем десериализована для внедрения. Это означает, что все привязанные параметры и контекст выполнения будут потеряны. Необходимо указать только один из files или func .

    Функция func выглядит так:

    () => {...}

StyleOrigin

Источник изменения стиля. Подробнее см. в разделе «Истоки стиля» .

Перечисление

«АВТОР»

"ПОЛЬЗОВАТЕЛЬ"

Методы

executeScript()

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

Внедряет скрипт в целевой контекст. По умолчанию скрипт запускается в момент document_idle или немедленно, если страница уже загружена. Если установлено свойство injectImmediately , скрипт будет внедрен без ожидания, даже если страница ещё не загрузилась. Если результат скрипта соответствует обещанию, браузер дождётся его завершения и вернёт полученное значение.

Параметры

  • инъекция

    Детали скрипта, который необходимо внедрить.

Возврат

getRegisteredContentScripts()

Хром 96+
chrome.scripting.getRegisteredContentScripts(
  filter?: ContentScriptFilter,
)
: Promise<RegisteredContentScript[]>

Возвращает все динамически зарегистрированные скрипты содержимого для этого расширения, соответствующие заданному фильтру.

Параметры

  • фильтр

    ContentScriptFilter необязательный

    Объект для фильтрации динамически зарегистрированных скриптов расширения.

Возврат

insertCSS()

chrome.scripting.insertCSS(
  injection: CSSInjection,
)
: Promise<void>

Вставляет таблицу стилей CSS в целевой контекст. Если указано несколько фреймов, неудачные внедрения игнорируются.

Параметры

  • инъекция

    Подробная информация о стилях для вставки.

Возврат

  • Обещание<void>

    Хром 90+

registerContentScripts()

Хром 96+
chrome.scripting.registerContentScripts(
  scripts: RegisteredContentScript[],
)
: Promise<void>

Регистрирует один или несколько скриптов контента для этого расширения.

Параметры

  • сценарии

    Содержит список скриптов для регистрации. Если при разборе скрипта/проверке файла возникли ошибки или указанные идентификаторы уже существуют, скрипты не регистрируются.

Возврат

  • Обещание<void>

removeCSS()

Хром 90+
chrome.scripting.removeCSS(
  injection: CSSInjection,
)
: Promise<void>

Удаляет таблицу стилей CSS, ранее вставленную этим расширением из целевого контекста.

Параметры

  • инъекция

    Подробная информация об удаляемых стилях. Обратите внимание, что свойства css , files и origin должны точно соответствовать таблице стилей, вставленной с помощью insertCSS . Попытка удалить несуществующую таблицу стилей невозможна.

Возврат

  • Обещание<void>

unregisterContentScripts()

Хром 96+
chrome.scripting.unregisterContentScripts(
  filter?: ContentScriptFilter,
)
: Promise<void>

Отменяет регистрацию скриптов содержимого для этого расширения.

Параметры

  • фильтр

    ContentScriptFilter необязательный

    Если указано, отменяет регистрацию только тех скриптов динамического контента, которые соответствуют фильтру. В противном случае отменяются все скрипты динамического контента расширения.

Возврат

  • Обещание<void>

updateContentScripts()

Хром 96+
chrome.scripting.updateContentScripts(
  scripts: RegisteredContentScript[],
)
: Promise<void>

Обновляет один или несколько скриптов контента для этого расширения.

Параметры

  • сценарии

    Содержит список скриптов для обновления. Свойство обновляется только для существующего скрипта, если оно указано в этом объекте. Если при разборе скрипта/проверке файла возникают ошибки или если указанные идентификаторы не соответствуют полностью зарегистрированному скрипту, скрипты не обновляются.

Возврат

  • Обещание<void>