Описание
Используйте API offscreen для создания и управления документами, которые не отображаются на экране.
Разрешения
offscreenЧтобы использовать Offscreen API, объявите разрешение "offscreen" в манифесте расширения. Пример:
{
"name": "My extension",
...
"permissions": [
"offscreen"
],
...
}
Доступность
Основные понятия и использование
У сервис-воркеров нет доступа к DOM, а многие сайты используют Content Security Policy, ограничивающие функциональность скриптов контента. Offscreen API позволяет расширению использовать DOM API в скрытом документе, не прерывая работу пользователя открытием новых окон или вкладок. runtime API – единственный API расширений, поддерживаемый невидимыми документами.
Страницы, загруженные как фоновые документы, обрабатываются иначе, чем другие типы страниц расширений.
Разрешения расширения распространяются на невидимые документы, но с ограничениями на доступ к API расширения. Например, поскольку browser.runtime API – единственный API расширений, поддерживаемый офскрин-документами, обмен сообщениями должен осуществляться с помощью членов этого API.
Ниже перечислены другие отличия офлайн-документов от обычных страниц.
- URL документа за пределами экрана должен быть статичным HTML-файлом, входящим в состав расширения.
- Нельзя выбрать документ, который не виден на экране.
- Документ вне экрана – это экземпляр
window, но значение его свойстваopenerвсегда равноnull. - Хотя пакет расширения может содержать несколько документов, находящихся за пределами экрана, в установленном расширении может быть открыт только один такой документ. Если расширение работает в разделенном режиме с активным профилем инкогнито, в обычном и режиме инкогнито может быть по одному документу вне экрана.
Используйте browser.offscreen.createDocument() и browser.offscreen.closeDocument(), чтобы создать и закрыть закадровый документ. Для createDocument() требуется url документа, причина и обоснование:
browser.offscreen.createDocument({
url: 'off_screen.html',
reasons: ['CLIPBOARD'],
justification: 'reason for needing the document',
});
Причины
Список допустимых причин приведен в разделе Причины. Причины указываются при создании документа, чтобы определить срок его хранения. Причина AUDIO_PLAYBACK задает закрытие документа через 30 секунд без воспроизведения аудио. Для всех остальных причин ограничения по времени жизни не задаются.
Примеры
Как поддерживать жизненный цикл документа, который не виден на экране
В следующем примере показано, как убедиться, что документ за пределами экрана существует. Функция setupOffscreenDocument() вызывает runtime.getContexts(), чтобы найти существующий документ за пределами экрана или создать его, если он ещё не существует.
let creating; // A global promise to avoid concurrency issues
async function setupOffscreenDocument(path) {
// Check all windows controlled by the service worker to see if one
// of them is the offscreen document with the given path
const offscreenUrl = browser.runtime.getURL(path);
const existingContexts = await browser.runtime.getContexts({
contextTypes: ['OFFSCREEN_DOCUMENT'],
documentUrls: [offscreenUrl]
});
if (existingContexts.length > 0) {
return;
}
// create offscreen document
if (creating) {
await creating;
} else {
creating = browser.offscreen.createDocument({
url: path,
reasons: ['CLIPBOARD'],
justification: 'reason for needing the document',
});
await creating;
creating = null;
}
}
Прежде чем отправлять сообщение в документ, который не отображается на экране, вызовите setupOffscreenDocument(), чтобы убедиться, что документ существует, как показано в следующем примере.
browser.action.onClicked.addListener(async () => {
await setupOffscreenDocument('off_screen.html');
// Send message to offscreen document
browser.runtime.sendMessage({
type: '...',
target: 'offscreen',
data: '...'
});
});
Полные примеры можно найти в демонстрационных версиях offscreen-clipboard и offscreen-dom на GitHub.
До версии Chrome 116: как проверить, открыт ли документ вне экрана
runtime.getContexts() был добавлен в Chrome 116. В более ранних версиях Chrome для проверки наличия существующего документа вне экрана используйте clients.matchAll():
async function hasOffscreenDocument() {
if ('getContexts' in browser.runtime) {
const contexts = await browser.runtime.getContexts({
contextTypes: ['OFFSCREEN_DOCUMENT'],
documentUrls: [OFFSCREEN_DOCUMENT_PATH]
});
return Boolean(contexts.length);
} else {
const matchedClients = await clients.matchAll();
return matchedClients.some(client => {
return client.url.includes(browser.runtime.id);
});
}
}
Типы
CreateParameters
Свойства
-
без объяснения причин
string
Строка, предоставленная разработчиком, в которой более подробно объясняется необходимость фонового контекста. Агент пользователя _может_ использовать это значение для показа пользователю.
-
причины
Причина[]
Причины, по которым расширение создает документ вне экрана.
-
url
string
Относительный URL, который нужно загрузить в документ.
Reason
Перечисление
"TESTING"
Причина, используемая только для тестирования.
"AUDIO_PLAYBACK"
Указывает, что воспроизведение аудио осуществляется с помощью невидимого документа.
"IFRAME_SCRIPTING"
Указывает, что для изменения контента iframe внеэкранному документу необходимо встроить и запрограммировать iframe.
"DOM_SCRAPING"
Указывает, что для извлечения информации из документа, находящегося за пределами экрана, необходимо встроить в него окно iframe и проанализировать его DOM.
"BLOBS"
Указывает, что невидимый документ должен взаимодействовать с объектами Blob (включая URL.createObjectURL()).
"DOM_PARSER"
Указывает, что в документе за пределами экрана необходимо использовать DOMParser API.
"USER_MEDIA"
Указывает, что невидимый документ должен взаимодействовать с медиапотоками из пользовательского медиаконтента (например, getUserMedia()).
"DISPLAY_MEDIA"
Указывает, что документ за пределами экрана должен взаимодействовать с медиапотоками из медиаконтента на экране (например, getDisplayMedia()).
"WEB_RTC"
Указывает, что для работы с невидимым документом необходимо использовать WebRTC API.
"CLIPBOARD"
Указывает, что невидимый документ должен взаимодействовать с Clipboard API.
"LOCAL_STORAGE"
Указывает, что невидимому документу требуется доступ к localStorage.
"WORKERS"
Указывает, что для документа за пределами экрана необходимо создать работников.
"BATTERY_STATUS"
Указывает, что для работы с документом вне экрана необходимо использовать navigator.getBattery.
"MATCH_MEDIA"
Указывает, что в документе за пределами экрана необходимо использовать window.matchMedia.
"GEOLOCATION"
Указывает, что для работы невидимого документа необходимо использовать navigator.geolocation.
Методы
closeDocument()
chrome.offscreen.closeDocument(): Promise<void>
Закрывает текущий скрытый документ для расширения.
Возвраты
-
Promise<void>
Обещание, которое выполняется, когда документ, находящийся за пределами экрана, закрыт.
createDocument()
chrome.offscreen.createDocument(
parameters: CreateParameters,
): Promise<void>
Создает новый документ вне экрана для расширения.
Параметры
-
Параметры
Параметры, описывающие документ, который нужно создать за пределами экрана.
Возвраты
-
Promise<void>
Промис, который разрешается, когда создается документ за пределами экрана и завершается его первоначальная загрузка страницы.
hasDocument()
chrome.offscreen.hasDocument(): Promise<boolean>
Определяет, есть ли у расширения активный документ.
Возвраты
-
Promise<boolean>
Объект Promise, который разрешается результатом проверки наличия активного фонового документа у расширения.