Chrome incompatibilities 编辑
Extensions built with WebExtension APIs are designed to be compatible with Chrome and Opera extensions. As far as possible, extensions written for those browsers should run on Firefox with minimal changes.
However, there are significant differences between Chrome, Firefox, and Edge. In particular:
Support for JavaScript APIs differs across browsers. See Browser support for JavaScript APIs for more details.
Support for
manifest.json
keys differs across browsers. See the "Browser compatibility" section in themanifest.json
page for more details.Javascript APIs:
- In Chrome
- JavaScript APIs are accessed under the
chrome
namespace. (cf. Chrome bug 798169) - In Firefox and Edge
- They are accessed under the
browser
namespace.
Asynchronous APIs:
- In Chrome and Edge
- Asynchronous APIs are implemented using callbacks. (cf. Chrome bug 328932)
- In Firefox
- Asynchronous APIs are implemented using promises.
The rest of this page summarizes these and other incompatibilities.
JavaScript APIs
Callbacks and the chrome.* namespace
- In Chrome
- Extensions access privileged JavaScript APIs using the
chrome
namespace.chrome.browserAction.setIcon({path: "path/to/icon.png"});
- In Firefox (via the WebExtension API)
- The equivalent APIs are accessed using the
browser
namespace.browser.browserAction.setIcon({path: "path/to/icon.png"});
Many of the APIs are asynchronous.
- In Chrome
- Asynchronous APIs use callbacks to return values, and
runtime.lastError
to communicate errors.function logCookie(c) { if (chrome.runtime.lastError) { console.error(chrome.runtime.lastError); } else { console.log(c); } } chrome.cookies.set( {url: "/wiki/"}, logCookie );
- In Firefox (via the WebExtension API)
- Asynchronous APIs use promises to return values instead.
function logCookie(c) { console.log(c); } function logError(e) { console.error(e); } let setCookie = browser.cookies.set( {url: "/wiki/"} ); setCookie.then(logCookie, logError);
Firefox supports both the chrome and browser namespaces
As a porting aid, the Firefox implementation of WebExtensions supports chrome
, using callbacks, as well as browser
, using promises. This means that many Chrome extensions will just work in Firefox without any changes.
Note: However, this is not part of the WebExtensions standard. and may not be supported by all compliant browsers.
If you choose to write your extension to use browser
and promises, then Firefox also provides a polyfill that will enable it to run in Chrome: https://github.com/mozilla/webextension-polyfill.
Partially supported APIs
The page Browser support for JavaScript APIs includes compatibility tables for all APIs that have any support in Firefox. Where there are caveats around support for a given API item, this is indicated in these tables with an asterisk "*" and in the reference page for the API item, the caveats are explained.
These tables are generated from compatibility data stored as JSON files in GitHub.
The rest of this section describes compatibility issues that are not already captured in the tables.
notifications
For
notifications.create()
, withtype "basic"
:- In Firefox
iconUrl
is optional.- In Chrome
iconUrl
is required.
When the user clicks on a notification:
- In Firefox
- The notification is cleared immediately.
- In Chrome
- This is not the case.
If you call
notifications.create()
more than once in rapid succession:- In Firefox, the notifications may not display at all. Waiting to make subsequent calls until within the
chrome.notifications.create()
callback function is not a sufficient delay to prevent this.
- In Firefox, the notifications may not display at all. Waiting to make subsequent calls until within the
proxy
Firefox's Proxy API followed a completely different design from Chrome's Proxy API.
- In Chrome
- An extension can register a PAC file, but can also define explicit proxying rules.
- In Firefox
- The proxy API only supports the PAC file approach (since this is also possible using extended PAC files). Note: Because this API is incompatible with Chrome's
proxy
API, the Firefox proxy API is only available through thebrowser
namespace.
tabs
When using
tabs.executeScript()
ortabs.insertCSS()
:- In Firefox
- Relative URLs passed are resolved relative to the current page URL.
- In Chrome
- These URLs are resolved relative to the extension's base URL.
To work cross-browser, you can specify the path as an absolute URL, starting at the extension's root, like this:
/path/to/script.js
When :
- In Firefox
- Querying tabs by URL with
tabs.query()
requires the"tabs"
permission. - In Chrome
- querying tabs by URL with
tabs.query()
It's possible without the"tabs"
permission, but will limit results to tabs whose URLs match host permissions.
When calling
tabs.remove()
:- In Firefox
- The
tabs.remove()
promise is fulfilled after thebeforeunload
event. - In Chrome
- The callback does not wait for
beforeunload
.
webRequest
- In Firefox
- Requests can be redirected only if their original URL uses the
http:
orhttps:
scheme. - The
activeTab
permission does not allow intercepting network requests in the current tab. (See bug 1617479) - Events are not fired for system requests (for example, extension upgrades or searchbar suggestions).
- From Firefox 57 onwards: Firefox makes an exception for extensions that need to intercept
webRequest.onAuthRequired
for proxy authorization. See the documentation forwebRequest.onAuthRequired
.
- From Firefox 57 onwards: Firefox makes an exception for extensions that need to intercept
- If an extension wants to redirect a public (e.g., HTTPS) URL to an extension page, the extension's
manifest.json
file must contain aweb_accessible_resources
key with the URL of the extension page.Note: Any website may then link or redirect to that URL, and extensions should treat any input (POST data, for example) as if it came from an untrusted source, just as a normal web page should.
- Requests can be redirected only if their original URL uses the
When using
browser.webRequest.*
:- In Firefox (starting from Firefox 52)
- Some of the
browser.webRequest.*
APIs allow returning Promises that resolveswebRequest.BlockingResponse
asynchronously. - In Chrome
- Only
webRequest.onAuthRequired
supports asynchronouswebRequest.BlockingResponse
via supplying'asyncBlocking'
.
windows
- In Firefox
onFocusChanged
will trigger multiple times for a given focus change.
Unsupported APIs
declarativeContent
- In Firefox
- Chrome's
declarativeContent
API has not yet been implemented in Firefox. - In addition, Firefox will not be supporting the
declarativeContent.RequestContentScript
API (which is rarely used, and is unavailable in stable releases of Chrome).
Miscellaneous incompatibilities
URLs in CSS
- In Firefox
- URLs in injected CSS files are resolved relative to the CSS file itself.
- In Chrome
- URLs in injected CSS files are resolved relative to the page they are injected into.
Additional incompatibilities
web_accessible_resources
- In Chrome
- When a resource is listed in
web_accessible_resources
, it is accessible aschrome-extension://«your-extension-id»/«path/to/resource»
. The extension ID is fixed for a given extension. - In Firefox
- Resources are assigned a random UUID that changes for every instance of Firefox:
moz-extension://«random-UUID»/«path/to/resource»
. This randomness can prevent you from doing a few things, such as add your specific extension's URL to another domain's CSP policy.
Manifest "key" property
- In Chrome
- When working with an unpacked extension, the manifest may include a
"key"
property to pin the extension ID across different machines. This is mainly useful when working withweb_accessible_resources
. - In Firefox
- Since Firefox uses random UUIDs for
web_accessible_resources
, this property is unsupported.
Content script requests happen in the context of extension, not content page
- In Chrome
- When a content script makes a request (for example, using
fetch()
) to a relative URL (like/api
), it will be sent tohttps://example.com/api
. - In Firefox
- When a content script makes a request, you must provide absolute URLs.
Sharing variables between content scripts
- In Firefox
- You cannot share variables between content scripts by assigning them to
this.{variableName}
in one script and then attempting to access them usingwindow.{variableName}
in another. This is a limitation created by the sandbox environment in Firefox. This limitation may be removed, see bug 1208775. Content script lifecycle during navigation
- In Chrome
- Content scripts are destroyed when the user navigates away from a web page. If the user then returns to the page through history, by clicking the back button, the content script is injected into the web page again.
- In Firefox
Content scripts remain injected in a web page after the user has navigated away, however, window object properties are destroyed. For example, if a content script sets
window.prop1 = "prop"
and the user then navigates away and returns to the pagewindow.prop1
is undefined. This issue is tracked in bug 1525400 .To mimic the behavior of Chrome, listen for the pageshow and pagehide events. Then simulate the injection or destruction of the content script.
"per-tab" zoom behavior
- In Chrome
- Zoom changes are reset on navigation; navigating a tab will always load pages with their per-origin zoom factors.
- In Firefox
The zoom level persists across page loads and navigation within the tab. in Chrome-based browsers
manifest.json keys
The main manifest.json
page includes a table describing browser support for manifest.json
keys. Where there are caveats around support for a given key, this is indicated in the table with an asterisk "*" and in the reference page for the key, the caveats are explained.
These tables are generated from compatibility data stored as JSON files in GitHub.
Native messaging
Connection-based messaging arguments
- On Linux and Mac
- Chrome passes one argument to the native app, which is the origin of the extension that started it, in the form:
chrome-extension://«extensionID»
. This enables the app to identify the extension. - On Windows
Chrome passes two arguments:
- The origin of the extension
- A handle to the Chrome native window that started the app
allowed_extensions
- In Firefox
- The manifest key is called
allowed_extensions
. - In Chrome
- The manifest key is called
allowed_origins
instead.
App manifest location
- In Chrome
- The app manifest is expected in a different place. See Native messaging host location in the Chrome docs.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论