Описание
Используйте chrome.scripting API, чтобы выполнять скрипты в разных контекстах.
Разрешения
scriptingДоступность
Манифест
Чтобы использовать 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
Свойства
-
ids
string[] необязательно
Если указать этот параметр,
getRegisteredContentScriptsбудет возвращать только скрипты с идентификаторами из этого списка.
CSSInjection
Свойства
-
css
Строка (необязательно)
Строка, содержащая CSS для внедрения. Необходимо указать только одно значение:
filesилиcss. -
файлы
string[] необязательно
Путь к файлам CSS, которые нужно внедрить, относительно корневого каталога расширения. Необходимо указать только одно значение:
filesилиcss. -
происхождение
StyleOrigin необязательный
Источник стиля для вставки. Значение по умолчанию –
'AUTHOR'. -
target
Сведения о цели, в которую нужно вставить CSS.
ExecutionWorld
Среда 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
Свойства
-
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Должно ли внедрение быть запущено в целевом объекте как можно скорее. Обратите внимание, что это не гарантирует внедрение до загрузки страницы, поскольку страница может быть уже загружена к моменту, когда скрипт достигнет цели.
-
target
Сведения о цели, в которую нужно внедрить скрипт.
-
мир
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()
browser.scripting.getRegisteredContentScripts(
filter?: ContentScriptFilter,
): Promise<RegisteredContentScript[]>
Возвращает все динамически зарегистрированные скрипты контента для этого расширения, соответствующие заданному фильтру.
Параметры
-
фильтр
ContentScriptFilter необязательный
Объект для фильтрации динамически зарегистрированных скриптов расширения.
Возвраты
-
Promise<RegisteredContentScript[]>
insertCSS()
browser.scripting.insertCSS(
injection: CSSInjection,
): Promise<void>
Вставляет таблицу стилей CSS в целевой контекст. Если указано несколько фреймов, неудачные вставки игнорируются.
Параметры
-
инъекция
Сведения о вставляемых стилях.
Возвраты
-
Promise<void>
Chrome 90 и более поздних версий browser.* начиная с Chrome 148Возвращает объект Promise, который распознается после завершения вставки.
registerContentScripts()
browser.scripting.registerContentScripts(
scripts: RegisteredContentScript[],
): Promise<void>
Регистрирует один или несколько скриптов обработки контента для этого расширения.
Параметры
-
скрипты
Содержит список скриптов, которые нужно зарегистрировать. Если при синтаксическом анализе скрипта или проверке файла возникнут ошибки или если указанные идентификаторы уже существуют, скрипты не будут зарегистрированы.
Возвраты
-
Promise<void>
Возвращает объект Promise, который распознается, когда скрипты полностью зарегистрированы, или отклоняется в случае ошибки.
removeCSS()
browser.scripting.removeCSS(
injection: CSSInjection,
): Promise<void>
Удаляет таблицу стилей CSS, которая ранее была вставлена этим расширением из целевого контекста.
Параметры
-
инъекция
Сведения о стилях, которые нужно удалить. Обратите внимание, что свойства
css,filesиoriginдолжны точно соответствовать таблице стилей, вставленной с помощьюinsertCSS. Попытка удалить несуществующую таблицу стилей не приведет к результату.
Возвраты
-
Promise<void>
Возвращает объект Promise, который распознается после завершения удаления.
unregisterContentScripts()
browser.scripting.unregisterContentScripts(
filter?: ContentScriptFilter,
): Promise<void>
Отменяет регистрацию скриптов обработки контента для этого расширения.
Параметры
-
фильтр
ContentScriptFilter необязательный
Если указано, отменяет регистрацию только тех скриптов динамического контента, которые соответствуют фильтру. В противном случае регистрация всех скриптов динамического контента расширения будет отменена.
Возвраты
-
Promise<void>
Возвращает объект Promise, который распознается после отмены регистрации скриптов или отклоняется в случае ошибки.
updateContentScripts()
browser.scripting.updateContentScripts(
scripts: RegisteredContentScript[],
): Promise<void>
Обновляет один или несколько скриптов контента для этого расширения.
Параметры
-
скрипты
Содержит список скриптов, которые нужно обновить. Свойство обновляется для существующего скрипта, только если оно указано в этом объекте. Если при синтаксическом анализе скрипта или проверке файла возникнут ошибки или если указанные идентификаторы не соответствуют полностью зарегистрированному скрипту, то скрипты не будут обновлены.
Возвраты
-
Promise<void>
Возвращает объект Promise, который распознается после обновления скриптов или отклоняется в случае ошибки.