w3c / webextensions

Charter and administrivia for the WebExtensions Community Group (WECG)
Other
576 stars 50 forks source link

[DNR] main_frame redirect to an extension page + accessing the original URL and POST data #610

Open tophf opened 1 month ago

tophf commented 1 month ago

Supersedes #604 with a different, more focused use case: redirecting an entire tab (optionally a frame) to a custom handler.

Extensions like Tapermonkey/Violentmonkey/Stylus/JSONViewer and others want to redirect an entire tab (or frame) based on a URL or on a Content-Type response header (soon will be possible via DNR) to their own built-in UI page. URLs ending on .json, .user.js or .user.css and such, so this is not solved by custom protocol handlers.

Primary goals

  1. The original URL must be exposed to the extension page.
  2. The extension page should not be exposed to the web:
    • to avoid redundancy as main_frame/sub_frame navigation is done by the browser's DNR handler, not by a web page;
    • to improve security as Chrome still doesn't implement use_dynamic_url;
    • to improve API ergonomics by removing a non-obvious requirement.
  3. Provide POST data from submitted forms to allow extensions to preprocess it before uploading to the server.

Optional goal

  1. Support sub_frame redirection in addition to main_frame.
    Although this is extremely rare to have a custom viewer in a frame, AFAIK, but it seems reasonable for consistency.

ManifestV2

ManifestV3

It's complicated and problematic since normal extensions can't use webRequestBlocking anymore:

Possible solutions for goal 1: exposing the original URL

  1. As document.referrer i.e. not exposed visually.
  2. As an auto-appended URL parameter ?url=.... accessible as new URLSearchParams(location.search).get('url'). It may be appended as &url=... if the extension path already contains ? e.g. "/foo.html?param=1".
    If deemed desirable, this behavior may be disabled by default, opt-in via "originalUrlAsParameter": "url".

Possible solutions for goal 2: redirection without self-exposure

  1. extensionHandler: 'foo.html'. The name suggests that the extension handles the page, like PDF viewer in Chrome.
  2. extensionTabHandler: 'foo.html'. A more self-explanatory name if we want to support only main_frame navigation.
  3. extensionNavigationHandler: 'foo.html'. Makes it even more obvious that this is only for navigation redirects.
  4. extensionPathForNavigation: 'foo.html'. Also preserves continuity with the existing extensionPath.
  5. resourcesTypes: ['main_frame', 'sub_frame'] would automatically allow extensionPath: 'foo.html' to redirect to the extension's foo.html without exposing it in web_accessible_resources. This is not explicit, though.

Possible solutions for goal 3: POST data access

  1. chrome.declarativeNetRequest.redirectedRequest getter or getRedirectedRequest() method to get all info
  2. chrome.declarativeNetRequest.requestBody getter or getRequestBody() method to get only the body