browser.scripting

Описание

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

Разрешения

scripting

Доступность

Chrome 88+ browser.* начиная с Chrome 148 MV3+

Манифест

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

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

Основные понятия и использование

С помощью API browser.scripting можно внедрять код JavaScript и CSS на сайты. Это похоже на то, что вы можете делать со скриптами контента. Но используя пространство имен browser.scripting, расширения могут принимать решения во время выполнения.

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

С помощью параметра target можно указать цель для внедрения JavaScript или CSS.

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

function getTabId() { ... }

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

Чтобы запустить скрипт во всех фреймах указанной вкладки, задайте для логического значения allFrames значение true.

function getTabId() { ... }

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

Вы также можете внедрить скрипт в определенные фреймы вкладки, указав их идентификаторы. Дополнительную информацию об идентификаторах фреймов можно найти в документации по API browser.webNavigation.

function getTabId() { ... }

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

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

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

Файлы

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

function getTabId() { ... }

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

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

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

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

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

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

browser.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;
}

browser.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; }";

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

Обработка результатов

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

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

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

Объекты Promise

Если в результате выполнения скрипта возвращается объект Promise, 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;
}

browser.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 browser.scripting.getRegisteredContentScripts();
    const scriptIds = scripts.map(script => script.id);
    return browser.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 browser.scripting, установите пример скрипта из хранилища примеров расширений Chrome.

Типы

ContentScriptFilter

Chrome 96 и более поздние версии browser.* начиная с Chrome 148

Свойства

  • ids

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

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

CSSInjection

Свойства

  • css

    Строка (необязательно)

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

  • файлы

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

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

  • происхождение

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

    Источник стиля для вставки. Значение по умолчанию – 'AUTHOR'.

  • Сведения о цели, в которую нужно вставить CSS.

ExecutionWorld

Chrome 95 и более поздних версий browser.* начиная с Chrome 148

Среда JavaScript, в которой будет выполняться скрипт.

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

"ISOLATED"
Указывает на изолированную среду, которая является уникальной средой выполнения для этого расширения.

"MAIN"
Указывает на основную среду DOM, которая является средой выполнения, общей с JavaScript на хост-странице.

InjectionResult

Свойства

  • documentId

    string

    Chrome 106 и более поздних версий browser.* начиная с Chrome 148

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

  • frameId

    число

    Chrome 90 и более поздних версий browser.* начиная с Chrome 148

    Фрейм, связанный с внедрением.

  • Результат

    any optional

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

InjectionTarget

Свойства

  • allFrames

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

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

  • documentIds

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

    Chrome 106 и более поздних версий browser.* начиная с Chrome 148

    Идентификаторы documentId, в которые нужно вставить данные. Это значение не должно быть задано, если задано значение frameIds.

  • frameIds

    number[] optional

    Идентификаторы фреймов, в которые нужно внедрить скрипт.

  • tabId

    число

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

RegisteredContentScript

Chrome 96 и более поздние версии browser.* начиная с Chrome 148

Свойства

  • allFrames

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

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

  • css

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

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

  • excludeMatches

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

    Исключает страницы, в которые в противном случае был бы внедрен этот скрипт. Подробнее о шаблонах соответствия…

  • id

    string

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

  • js

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

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

  • matchOriginAsFallback

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

    Chrome 119 и более поздних версий browser.* начиная с Chrome 148

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

  • соответствует

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

    Указывает, на какие страницы будет внедрен этот скрипт контента. Подробнее о шаблонах соответствия… Обязательно для registerContentScripts.

  • persistAcrossSessions

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

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

  • runAt

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

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

  • мир

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

    Chrome 102 и более поздних версий browser.* начиная с Chrome 148

    "Мир" JavaScript, в котором будет выполняться скрипт. Значение по умолчанию – ISOLATED.

ScriptInjection

Свойства

  • args

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

    Chrome 92 и более поздние версии browser.* начиная с Chrome 148

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

  • файлы

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

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

  • injectImmediately

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

    Chrome 102 и более поздних версий browser.* начиная с Chrome 148

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

  • Сведения о цели, в которую нужно внедрить скрипт.

  • мир

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

    Chrome 95 и более поздних версий browser.* начиная с Chrome 148

    "Мир" JavaScript, в котором будет выполняться скрипт. Значение по умолчанию – ISOLATED.

  • func

    void optional

    Chrome 92 и более поздние версии browser.* начиная с Chrome 148

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

    Функция func выглядит следующим образом:

    () => {...}

StyleOrigin

Источник изменения стиля. Подробнее о происхождении стилей…

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

"AUTHOR"

"USER"

Методы

executeScript()

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

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

Параметры

  • инъекция

    Сведения о скрипте, который нужно внедрить.

Возвраты

  • Promise<InjectionResult[]>

    Chrome 90 и более поздних версий browser.* начиная с Chrome 148

    Возвращает объект Promise, который распознается после завершения вставки. Результирующий массив содержит результат выполнения для каждого кадра, в котором внедрение прошло успешно.

getRegisteredContentScripts()

Chrome 96 и более поздние версии browser.* начиная с Chrome 148
browser.scripting.getRegisteredContentScripts(
  filter?: ContentScriptFilter,
)
: Promise<RegisteredContentScript[]>

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

Параметры

  • фильтр

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

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

Возвраты

insertCSS()

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

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

Параметры

  • инъекция

    Сведения о вставляемых стилях.

Возвраты

  • Promise<void>

    Chrome 90 и более поздних версий browser.* начиная с Chrome 148

    Возвращает объект Promise, который распознается после завершения вставки.

registerContentScripts()

Chrome 96 и более поздние версии browser.* начиная с Chrome 148
browser.scripting.registerContentScripts(
  scripts: RegisteredContentScript[],
)
: Promise<void>

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

Параметры

  • скрипты

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

Возвраты

  • Promise<void>

    Возвращает объект Promise, который распознается, когда скрипты полностью зарегистрированы, или отклоняется в случае ошибки.

removeCSS()

Chrome 90 и более поздних версий browser.* начиная с Chrome 148
browser.scripting.removeCSS(
  injection: CSSInjection,
)
: Promise<void>

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

Параметры

  • инъекция

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

Возвраты

  • Promise<void>

    Возвращает объект Promise, который распознается после завершения удаления.

unregisterContentScripts()

Chrome 96 и более поздние версии browser.* начиная с Chrome 148
browser.scripting.unregisterContentScripts(
  filter?: ContentScriptFilter,
)
: Promise<void>

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

Параметры

  • фильтр

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

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

Возвраты

  • Promise<void>

    Возвращает объект Promise, который распознается после отмены регистрации скриптов или отклоняется в случае ошибки.

updateContentScripts()

Chrome 96 и более поздние версии browser.* начиная с Chrome 148
browser.scripting.updateContentScripts(
  scripts: RegisteredContentScript[],
)
: Promise<void>

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

Параметры

  • скрипты

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

Возвраты

  • Promise<void>

    Возвращает объект Promise, который распознается после обновления скриптов или отклоняется в случае ошибки.