Spec-Zone.ru › Web Extensions

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

Скрипты фонового выполнения или фоновая страница позволяют отслеживать и реагировать на события в браузере, такие как переход на новую страницу, удаление закладки или закрытие вкладки.

Скрипты фонового выполнения или страница:

  • Персистентные – загружаются при запуске расширения и разгружаются при отключении или удалении расширения.
  • Неперсистентные (также известные как страницы событий) – загружаются только при необходимости для реагирования на событие и разгружаются, когда становятся бездействующими. Однако фоновая страница не разгружается, пока не будут закрыты все видимые представления и порты сообщений. Открытие представления не приводит к загрузке фоновой страницы, но препятствует её закрытию.

В Manifest V2 скрипты фонового выполнения или страница могут быть персистентными или неперсистентными. Неперсистентные скрипты фонового выполнения рекомендуются, так как они снижают затраты ресурсов вашего расширения. В Manifest V3 поддерживаются только неперсистентные скрипты фонового выполнения или страницы.

Если у вас есть персистентные скрипты фонового выполнения или страница в Manifest V2 и вы хотите подготовить своё расширение к миграции в Manifest V3, раздел Преобразование в неперсистентное содержит рекомендации по переходу скриптов или страницы к неперсистентной модели.

Среда выполнения скриптов фонового выполнения

API DOM

Скрипты фонового выполнения выполняются в контексте специальной страницы, называемой фоновой страницей. Это даёт им глобальный объект window, а также все стандартные API DOM, предоставляемые этим объектом.

Предупреждение: В Firefox фоновые страницы не поддерживают использование alert(), confirm() или prompt().

API WebExtension

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

Доступ к ресурсам из других доменов

Скрипты фонового выполнения могут выполнять запросы XHR к хостам, для которых у них есть разрешения на доступ к хосту.

Содержание веб-страниц

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

Политика безопасности содержимого

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

Дополнительные сведения см. в разделе Политика безопасности содержимого.

Реализация скриптов фонового выполнения

Этот раздел описывает, как реализовать неперсистентный скрипт фонового выполнения.

Указание скриптов фонового выполнения

В вашем расширении вы включаете скрипт или скрипты фонового выполнения, если они нужны, используя ключ "background" в manifest.json. Для расширений Manifest V2 свойство persistent должно быть false для создания неперсистентного скрипта. Оно может быть опущено для расширений Manifest V3 или должно быть установлено в false, так как скрипты всегда неперсистентны в Manifest V3. Включение "type": "module" загружает скрипты фонового выполнения как ES модули.

"background": {
  "scripts": ["background-script.js"],
  "persistent": false,
  "type": "module"
}

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

Однако, если вам нужно определённое содержимое на фоновой странице, вы можете указать её. Тогда вы указываете свой скрипт из страницы, а не используя свойство "scripts" . До появления свойства "type" в ключе "background" это был единственный способ включить ES модули. Вы указываете фоновую страницу так:

  • manifest.json
    "background": {
      "page": "background-page.html",
      "persistent": false
    }
    
  • background-page.html
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <script type="module" src="background-script.js"></script>
      </head>
    </html>
    

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

Инициализация расширения

Прослушивайте событие runtime.onInstalled для инициализации расширения при установке. Используйте это событие для установки состояния или однократной инициализации. Для расширений с страницами событий здесь следует использовать API со состоянием, например, контекстное меню, созданное с помощью browser.menus.create.

browser.runtime.onInstalled.addListener(() => {
  browser.contextMenus.create({
    "id": "sampleContextMenu",
    "title": "Sample Context Menu",
    "contexts": ["selection"]
  });
});

Добавление обработчиков событий

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

Обработчики событий должны регистрироваться синхронно с самого начала работы страницы.

browser.runtime.onInstalled.addListener(() => {
  browser.contextMenus.create({
    "id": "sampleContextMenu",
    "title": "Sample Context Menu",
    "contexts": ["selection"]
  });
});

// This will run when a bookmark is created.
browser.bookmarks.onCreated.addListener(() => {
  // do something
});

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

window.onload = () => {
  // WARNING! This event is not persisted, and will not restart the event page.
  browser.bookmarks.onCreated.addListener(() => {
    // do something
  });
}

Сделайте так:

browser.tabs.onUpdated.addListener(() => {
  // This event is run in the top level scope of the event page, and will persist, allowing
  // it to restart the event page if necessary.
});

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

browser.runtime.onMessage.addListener(function messageListener(message, sender, reply) {
  browser.runtime.onMessage.removeListener(messageListener);
});

Фильтрация событий

Используйте API, поддерживающие фильтры событий, чтобы ограничить обработчики событиями, которые нужны расширению. Если расширение прослушивает tabs.onUpdated, используйте событие webNavigation.onCompleted с фильтрами вместо него, так как API вкладок не поддерживает фильтры.

browser.webNavigation.onCompleted.addListener(() => {
  console.log("This is my favorite website!");
}, { url: [{ urlMatches : 'https://www.mozilla.org/' }] });

Реагирование на обработчики событий

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

browser.runtime.onMessage.addListener((message, callback) => {
  if (message.data === "setAlarm") {
    browser.alarms.create({delayInMinutes: 5})
  } else if (message.data === "runLogic") {
    browser.tabs.executeScript({file: 'logic.js'});
  } else if (message.data === "changeColor") {
    browser.tabs.executeScript(
      {code: 'document.body.style.backgroundColor="orange"'});
  };
});

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

Данные должны периодически сохраняться, чтобы не потерять важную информацию, если расширение аварийно завершит работу, не получив уведомление runtime.onSuspend. Используйте API хранилища для этого.

browser.storage.local.set({variable: variableInformation});

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

browser.runtime.onMessage.addListener((message, callback) => {
  if (message === 'hello') {
    sendResponse({greeting: 'welcome!'})
  } else if (message === 'goodbye') {
    browser.runtime.Port.disconnect();
  }
});

Скрипты фонового выполнения разгружаются после нескольких секунд бездействия. Однако если во время приостановки скрипта фонового выполнения другое событие активирует его, вызывается runtime.onSuspendCanceled, и скрипт фонового выполнения продолжает работу. Если требуется какая-либо очистка, прослушивайте runtime.onSuspend.

browser.runtime.onSuspend.addListener(() => {
  console.log("Unloading.");
  chrome.browserAction.setBadgeText({text: ""});
});

Однако предпочтительнее сохранять данные, а не полагаться на runtime.onSuspend. Это не позволяет выполнить необходимую очистку и не помогает в случае сбоя.

Преобразование в неперсистентное

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

Обновление файла manifest.json

В файле manifest.json вашего расширения измените значение свойства persistent ключа "background" на false для вашего скрипта или страницы.

"background": {
  …,
  "persistent": false
}

Перенос обработчиков событий

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

browser.runtime.onStartup.addListener(() => {
  // run startup function
})

Запись изменений состояния

Так как скрипты теперь открываются и закрываются по мере необходимости, используйте API хранилища для установки и получения состояний и значений. Используйте storage.local set для обновления на локальном компьютере.

browser.storage.local.set({ variable: variableInformation });

Используйте storage.local get для получения значения этой переменной.

browser.storage.local.get(['variable'], (result) => {
  let someVariable = result.variable;
  // Do something with someVariable
});
END_OF_DOCUMENT_MARKER

Изменение таймеров на будильники

Таймеры на основе DOM не остаются активными после того, как страница события стала бездействующей. Вместо этого используйте API alarms, если вам нужен таймер для пробуждения страницы события.

browser.alarms.create({delayInMinutes: 3.0})

Затем добавьте обработчик.

browser.alarms.onAlarm.addListener(() => {
  alert("Hello, world!")
});

Обновление вызовов для функций скрипта фонового сценария

Если скрипт содержимого или действие должны вызвать функцию, используйте runtime.getBackgroundPage, чтобы убедиться, что страница события работает. Если вызов необязателен (то есть необходим только если страница события активна), используйте extension.getBackgroundPage, который возвращает null если страница не работает.

document.getElementById('target').addEventListener('click', async () => {
  let backgroundPage = await window.runtime.getBackgroundPage();
  backgroundPage.backgroundFunction();
});

© 2005–2023 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Background_scripts

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API