Spec-Zone.ru › Web Extensions

Несовместимости с Chrome

Расширения, созданные с использованием API WebExtension, предназначены для совместимости с расширениями Chrome и Opera. По возможности, расширения, написанные для этих браузеров, должны работать в Firefox с минимальными изменениями.

Однако существуют значительные различия между Chrome, Firefox и Edge. В частности:

  • Поддержка JavaScript-API различается в разных браузерах. Подробнее см. Поддержка JavaScript-API в разных браузерах.
  • Поддержка manifest.json ключей различается в разных браузерах. Подробнее см. раздел "Совместимость с браузерами" на странице manifest.json.
  • JavaScript-API:
    • В Firefox: к JavaScript-API обращаются в пространстве имен browser.
    • В Chrome и Edge: к JavaScript-API обращаются в пространстве имен chrome. (см. ошибку Chrome 798169)
  • Асинхронные API:
    • В Firefox: асинхронные API реализованы с использованием промисов.
    • В Chrome и Edge: асинхронные API реализованы с использованием обратных вызовов. (см. ошибку Chrome 328932)

В остальной части этой страницы подведены итоги этим и другим несовместимостям.

JavaScript-API

Пространство имен chrome.* и browser.*

  • В Firefox: эквивалентные API доступны через пространство имен browser.
    browser.browserAction.setIcon({path: "path/to/icon.png"});
    
  • В Chrome: расширения обращаются к привилегированным JavaScript-API в пространстве имен chrome.
    chrome.browserAction.setIcon({path: "path/to/icon.png"});
    

Обратные вызовы и промисы

  • В Firefox: асинхронные API используют промисы для возврата значений вместо этого.
    function logCookie(c) {
      console.log(c);
    }
    
    function logError(e) {
      console.error(e);
    }
    
    let setCookie = browser.cookies.set(
      {url: "https://developer.mozilla.org/"}
    );
    setCookie.then(logCookie, logError);
    
  • В Chrome: асинхронные API используют обратные вызовы для возврата значений и runtime.lastError для передачи ошибок.
    function logCookie(c) {
      if (chrome.runtime.lastError) {
        console.error(chrome.runtime.lastError);
      } else {
        console.log(c);
      }
    }
    
    chrome.cookies.set(
      {url: "https://developer.mozilla.org/"},
      logCookie
    );
    

Firefox поддерживает оба пространства имен chrome и browser

Для облегчения переноса реализация WebExtensions в Firefox поддерживает chrome, используя обратные вызовы, а также browser, используя промисы. Это означает, что многие расширения Chrome будут работать в Firefox без каких-либо изменений.

Примечание: Однако это не является частью стандарта WebExtensions и может не поддерживаться всеми совместимыми браузерами.

Если вы хотите написать свое расширение, чтобы использовать browser и промисы, то Firefox также предоставляет полифил, который позволит ему работать в Chrome: https://github.com/mozilla/webextension-polyfill.

Частично поддерживаемые API

Страница Поддержка JavaScript-API в разных браузерах содержит таблицы совместимости для всех API, которые частично поддерживаются в Firefox. В случаях, когда есть замечания относительно поддержки того или иного элемента API, это указано в этих таблицах с звездочкой «*», а в справочной странице по элементу API поясняются эти замечания.

Эти таблицы сгенерированы из данных о совместимости, хранящихся в файлах JSON в GitHub.

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

API уведомлений

Для notifications.create(), с type "basic":

  • В Firefox: iconUrl является необязательным.
  • В Chrome: iconUrl является обязательным.

Когда пользователь нажимает на уведомление:

  • В Firefox: уведомление удаляется немедленно.
  • В Chrome: это не так.

Если вы вызываете notifications.create() более одного раза подряд:

  • В Firefox: в Firefox уведомления могут вообще не отображаться. Ожидание для последующих вызовов до начала выполнения обратного вызова chrome.notifications.create() не является достаточным временем ожидания для предотвращения этого.

API прокси

API прокси Firefox proxy имел совершенно иную структуру по сравнению с API прокси Chrome.

  • В Firefox: расширение может зарегистрировать файл PAC.
  • В Chrome: расширение может зарегистрировать файл PAC, но также может определить явные правила проксирования.

Поскольку этот API несовместим с API прокси Chrome proxy, API прокси Firefox доступен только через пространство имен browser.

API вкладок

При использовании tabs.executeScript() или tabs.insertCSS():

  • В Firefox: передаваемые относительные URL интерпретируются относительно текущего URL страницы.
  • В Chrome: эти URL интерпретируются относительно базового URL расширения.

Для кросс-браузерной работы можно указать путь в виде абсолютного URL, начинающегося с корня расширения, например:

/path/to/script.js

При запросе вкладок по URL tabs.query():

  • В Firefox: расширения должны иметь разрешение "tabs".
  • В Chrome: расширениям не нужно разрешение "tabs", но в результаты будут включены только вкладки, URL которых соответствуют разрешениям хоста расширения.

При вызове tabs.remove():

  • В Firefox: промис tabs.remove() выполняется после события beforeunload.
  • В Chrome: обратный вызов не ожидает события beforeunload.

API webrequest

  • В Firefox:
    • Перенаправление запросов возможно только если исходный URL использует схему http: или https:.
    • Разрешение activeTab не позволяет перехватывать сетевые запросы в текущей вкладке. (См. ошибку 1617479)
    • События не генерируются для системных запросов (например, обновление расширений или предложения в строке поиска).
      • С Firefox 57: Firefox делает исключение для расширений, которым необходимо перехватывать webRequest.onAuthRequired для авторизации прокси. См. документацию по webRequest.onAuthRequired.
    • Если расширение хочет перенаправить публичный (например, HTTPS) URL на страницу расширения, файл manifest расширения должен содержать ключ web_accessible_resources с URL страницы расширения.
      • Примечание: Любой веб-сайт может затем ссылаться или перенаправлять на этот URL, и расширения должны рассматривать любой ввод (например, данные POST) как поступающий от ненадежного источника, как и обычная веб-страница.

    • Некоторые API browser.webRequest.* позволяют возвращать промисы, которые разрешаются webRequest.BlockingResponse асинхронно.
  • В Chrome: только webRequest.onAuthRequired поддерживает асинхронное webRequest.BlockingResponse, используя 'asyncBlocking'.

API окон

  • В Firefox: вызовы onFocusChanged API windows будут срабатывать несколько раз при изменении фокуса.

Неподдерживаемые API

API declarativeContent

  • В Firefox: API declarativeContent Chrome ещё не реализован. Кроме того, Firefox не будет поддерживать API declarativeContent.RequestContentScript (который редко используется и недоступен в стабильных версиях Chrome).

Разные несовместимости

URL в CSS

  • В Firefox: URL в инжектированных файлах CSS разрешаются относительно самого файла CSS.
  • В Chrome: URL в инжектированных файлах CSS разрешаются относительно страницы, в которую они инжектированы.

Поддержка диалоговых окон в страницах фона

  • В Firefox: alert(), confirm() и prompt() не поддерживаются в страницах фона:

web_accessible_resources

  • В Firefox: Ресурсам присваивается случайный UUID, который меняется для каждой инстанции Firefox: moz-extension://«random-UUID»/«path». Эта случайность может помешать вам выполнить некоторые действия, такие как добавление URL вашего конкретного расширения в политику CSP другого домена.
  • В Chrome: Когда ресурс перечислен в web_accessible_resources, он доступен как chrome-extension://«your-extension-id»/«path». Идентификатор расширения фиксирован для данного расширения.

Свойство манифеста "key"

  • В Firefox: Поскольку Firefox использует случайные UUID для web_accessible_resources, это свойство не поддерживается.
  • В Chrome: При работе с нераспакованным расширением манифест может содержать "key" свойство для привязки идентификатора расширения к различным машинам. Это в основном полезно при работе с web_accessible_resources.

Запросы HTTP(S) скриптов содержимого

  • В Firefox: Когда скрипт содержимого выполняет запрос HTTP(S), вы обязательно должны указать абсолютные URL.
  • В Chrome: Когда скрипт содержимого выполняет запрос (например, используя fetch()) к относительному URL (например, /api), он будет отправлен в https://example.com/api.

Окружение скрипта содержимого

  • В Firefox: Глобальное пространство имен скрипта содержимого не строго равно window (Firefox bug 1208775). Более конкретно, глобальное пространство имен (globalThis) состоит из стандартных возможностей JavaScript, как обычно, плюс window в качестве прототипа глобального пространства имен. Большинство API DOM наследуются от страницы через window, через Xray vision для защиты скрипта содержимого от изменений со стороны веб-страницы. Скрипты содержимого могут сталкиваться с объектами JavaScript из собственного глобального пространства имен или с заворачиваемыми через Xray версиями со страницы веб-сайта.
  • В Chrome: Глобальное пространство имен window, а доступные API DOM, как правило, независимы от веб-страницы (кроме совместного использования базового DOM). Скрипты содержимого не могут напрямую получить доступ к объектам JavaScript со страницы веб-сайта.

Выполнение кода на веб-странице из скрипта содержимого

  • В Firefox: eval выполняет код в контексте скрипта содержимого, а window.eval выполняет код в контексте страницы. См. Использование eval в скриптах содержимого.
  • В Chrome: eval и window.eval всегда выполняет код в контексте скрипта содержимого, а не в контексте страницы.

Обмен переменными между скриптами содержимого

  • В Firefox: Вы не можете обмениваться переменными между скриптами содержимого, присваивая их this.{variableName} в одном скрипте, а затем пытаясь получить доступ к ним с помощью window.{variableName} в другом. Это ограничение, созданное песочницей Firefox. Это ограничение может быть устранено, см. Firefox bug 1208775.

Жизненный цикл скрипта содержимого во время навигации

  • В Firefox: Скрипты содержимого остаются инжектированными на веб-странице после того, как пользователь перешел на другую страницу, однако свойства объекта window уничтожаются. Например, если скрипт содержимого установит window.prop1 = "prop", а пользователь затем перейдет на другую страницу и вернется на страницу window.prop1, то window.prop1 будет undefined. Эта проблема отслеживается в Firefox bug 1525400. Чтобы смоделировать поведение Chrome, отслеживайте события pageshow и pagehide. Затем смоделируйте инъекцию или уничтожение скрипта содержимого.
  • В Chrome: Скрипты содержимого уничтожаются, когда пользователь переходит на другую веб-страницу. Если пользователь затем возвращается на страницу через историю, нажав кнопку "Назад", скрипт содержимого снова инжектируется на веб-страницу.

Поведение масштабирования "per-tab"

  • В Firefox: Уровень масштабирования сохраняется при переходе между страницами и навигации в рамках вкладки.
  • В Chrome: Изменения масштабирования сбрасываются при навигации; навигация по вкладке всегда загружает страницы с их факторами масштабирования по происхождению.

См. tabs.ZoomSettingsScope.

Ключи manifest.json

Основная страница manifest.json содержит таблицу, описывающую поддержку браузеров для manifest.json ключей. В случаях, когда есть оговорки относительно поддержки определенного ключа, это указывается в таблице звездочкой "*" и на странице справки по ключу подробно объясняются эти оговорки.

Эти таблицы сгенерированы из данных совместимости, хранящихся в виде JSON-файлов на GitHub.

Нативное сообщение

Аргументы месседжинга на основе соединений

В Linux и macOS: Chrome передает один аргумент в приложение, который является происхождением расширения, которое его запустило, в формате: chrome-extension://«extensionID/» (требуется конечный слэш). Это позволяет приложению идентифицировать расширение.

В Windows: Chrome передает два аргумента:

  1. Происхождение расширения
  2. Дескриптор окна Chrome, которое запустило приложение

Разрешенные расширения

  • В Firefox: Ключ манифеста называется allowed_extensions.
  • В Chrome: Ключ манифеста называется allowed_origins.

Расположение манифеста приложения

  • В Chrome: Манифест приложения ожидается в другом месте. См. Расположение хоста нативного сообщения в документации Chrome.

Сохранение приложения

  • В Firefox: Когда соединение нативного месседжинга закрывается, Firefox убивает дочерние процессы, если они не отвязались. В Windows браузер помещает процесс приложения в объект задания и убивает задание. Если приложение запускает другие процессы и хочет, чтобы они оставались открытыми после закрытия родительского приложения, приложение должно использовать CreateProcess, а не ShellExecute, чтобы запустить дополнительный процесс со флагом CREATE_BREAKAWAY_FROM_JOB.
END_OF_DOCUMENT_MARKER

Алгоритм клонирования данных

Некоторые расширенные API позволяют расширению отправлять данные из одной части расширения в другую, такие как runtime.sendMessage(), tabs.sendMessage(), runtime.onMessage, метод postMessage() объекта runtime.port и tabs.executeScript().

  • В Firefox: Используется алгоритм структурного клонирования.
  • В Chrome: Используется алгоритм сериализации JSON. В будущем может быть переключен на алгоритм структурного клонирования (задача 248548).

Алгоритм структурного клонирования поддерживает больше типов, чем алгоритм сериализации JSON. Заметным исключением являются (DOM) объекты с методом toJSON. DOM-объекты по умолчанию не клонируются и не сериализуются в JSON, но с помощью метода toJSON(), их можно сериализовать в JSON (но всё равно не клонировать с помощью алгоритма структурного клонирования). Примерами JSON-сериализуемых объектов, которые не поддерживают структурное клонирование, являются экземпляры URL и PerformanceEntry.

Расширения, которые полагаются на метод toJSON() алгоритма сериализации JSON, могут использовать JSON.stringify(), за которым следует JSON.parse(), чтобы гарантировать обмен сообщением, так как разобранное значение JSON всегда структурно клонируемо.

© 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/Chrome_incompatibilities

Spec-Zone.ru

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