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

Описание

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

Разрешения

scripting

Доступность

Хром 88+ МВ3+

Манифест

Чтобы использовать 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(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

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

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

    нить

    Хром 106+

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

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

    число

    Хром 90+

    Рамка, связанная с инъекцией.

  • результат

    любые дополнительные

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

InjectionTarget

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

  • всекадры

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

    Должен ли сценарий внедряться во все кадры на вкладке. По умолчанию ложь. Это не должно быть правдой, если указаны frameIds .

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

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

    Хром 106+

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

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

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

    Идентификаторы конкретных кадров, в которые необходимо внедрить.

  • идентификатор табуляции

    число

    Идентификатор вкладки, в которую необходимо внедрить.

RegisteredContentScript

Хром 96+

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

  • всекадры

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

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

  • CSS

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

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

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

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

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

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

    нить

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

  • js

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

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

  • matchOriginAsFallback

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

    Хром 119+

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

  • спички

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

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

  • PersistAcrossSessions

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

    Указывает, будет ли этот сценарий содержимого сохраняться в будущих сеансах. По умолчанию это правда.

  • запуститьAt

    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,
  callback?: function,
)

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

Параметры

  • инъекция

    Подробности сценария, который необходимо внедрить.

  • перезвонить

    функция необязательна

    Параметр callback выглядит так:

    (results: InjectionResult[]) => void

Возврат

  • Обещание< InjectionResult []>

    Хром 90+

    Промисы поддерживаются в Манифесте V3 и более поздних версиях, но обратные вызовы предусмотрены для обратной совместимости. Вы не можете использовать оба при одном вызове функции. Промис разрешается с тем же типом, который передается в обратный вызов.

getRegisteredContentScripts()

Обещание Chrome 96+
chrome.scripting.getRegisteredContentScripts(
  filter?: ContentScriptFilter,
  callback?: function,
)

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

Параметры

Возврат

  • Обещание< RegisteredContentScript []>

    Промисы поддерживаются в Манифесте V3 и более поздних версиях, но обратные вызовы предусмотрены для обратной совместимости. Вы не можете использовать оба при одном вызове функции. Промис разрешается с тем же типом, который передается в обратный вызов.

insertCSS()

Обещать
chrome.scripting.insertCSS(
  injection: CSSInjection,
  callback?: function,
)

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

Параметры

  • инъекция

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

  • перезвонить

    функция необязательна

    Параметр callback выглядит так:

    () => void

Возврат

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

    Хром 90+

    Промисы поддерживаются в Манифесте V3 и более поздних версиях, но обратные вызовы предусмотрены для обратной совместимости. Вы не можете использовать оба при одном вызове функции. Промис разрешается с тем же типом, который передается в обратный вызов.

registerContentScripts()

Обещание Chrome 96+
chrome.scripting.registerContentScripts(
  scripts: RegisteredContentScript[],
  callback?: function,
)

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

Параметры

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

  • перезвонить

    функция необязательна

    Параметр callback выглядит так:

    () => void

Возврат

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

    Промисы поддерживаются в Манифесте V3 и более поздних версиях, но обратные вызовы предусмотрены для обратной совместимости. Вы не можете использовать оба при одном вызове функции. Промис разрешается с тем же типом, который передается в обратный вызов.

removeCSS()

Обещание Chrome 90+
chrome.scripting.removeCSS(
  injection: CSSInjection,
  callback?: function,
)

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

Параметры

  • инъекция

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

  • перезвонить

    функция необязательна

    Параметр callback выглядит так:

    () => void

Возврат

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

    Промисы поддерживаются в Манифесте V3 и более поздних версиях, но обратные вызовы предусмотрены для обратной совместимости. Вы не можете использовать оба при одном вызове функции. Промис разрешается с тем же типом, который передается в обратный вызов.

unregisterContentScripts()

Обещание Chrome 96+
chrome.scripting.unregisterContentScripts(
  filter?: ContentScriptFilter,
  callback?: function,
)

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

Параметры

  • фильтр

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

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

  • перезвонить

    функция необязательна

    Параметр callback выглядит так:

    () => void

Возврат

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

    Промисы поддерживаются в Манифесте V3 и более поздних версиях, но обратные вызовы предусмотрены для обратной совместимости. Вы не можете использовать оба при одном вызове функции. Промис разрешается с тем же типом, который передается в обратный вызов.

updateContentScripts()

Обещание Chrome 96+
chrome.scripting.updateContentScripts(
  scripts: RegisteredContentScript[],
  callback?: function,
)

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

Параметры

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

  • перезвонить

    функция необязательна

    Параметр callback выглядит так:

    () => void

Возврат

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

    Промисы поддерживаются в Манифесте V3 и более поздних версиях, но обратные вызовы предусмотрены для обратной совместимости. Вы не можете использовать оба при одном вызове функции. Промис разрешается с тем же типом, который передается в обратный вызов.