我可以让浏览器扩展返回 Web 请求的自定义响应吗?

问题描述 投票:0回答:1

在 Firefox 或 Chrome(1) 扩展程序(使用 WebExtensions)中,是否可以中断请求并返回备用响应,从而阻止网络请求?我想做的是使用存储 API(动态)存储一些 html 数据,然后在浏览器尝试发送特定请求时返回该 html。

webRequest.onBeforeRequest似乎只支持取消请求或返回重定向。有没有办法重定向到返回数据的扩展内的某些内容?或者直接制作并返回响应的方法?

(1) Chrome 的 webRequest 文档似乎反映了与 Firefox 文档相同的现实,并且 Firefox 似乎故意采用了许多 WebExtensions 来与 Chrome 保持一致。

google-chrome-extension firefox-addon firefox-addon-webextensions chrome-webrequest
1个回答
0
投票

我不确定最初的提问者是否仍然关心 7 年前的问题,但可以重定向(或取消)网络请求并从

browser.storage
返回 HTML,从而阻止网络请求。

manifest.json

...
  "background": {
    "scripts": [
      "background.js"
    ]
  },
  "permissions": [
    "storage",
    "webRequest",
    "webRequestBlocking",
    "*://*/*"
  ],
  "web_accessible_resources": [
    "content.htm"
  ]
...

背景.js

( function () {
  'use strict';

  var
    baseURL = browser.runtime.getURL( 'content.htm' ) + '?q=';

  // filter requests by target
  // redirect into extension if hit
  function onRequest( e ) {
    var
      rc = {};

    // in practice, compare e.url to more than one value
    if ( e.url === 'https://www.youtube.com/watch?v=9xp1XWmJ_Wo' ) {
      rc = { redirectUrl: baseURL + encodeURIComponent( e.url ) };
    }
    return rc;
  }
  browser.webRequest.onBeforeRequest.addListener(
    onRequest, {
      types: [ 'main_frame' ],
      urls: [ '*://*/*' ]
    }, [
      'blocking'
    ]
  );
} () );

内容.htm

<!DOCTYPE html><html lang="en"><head>
  <title>Placeholder</title>
  <script src="content.js"></script>
</head><body>
</body></html>

内容.js

( function () {
  'use strict';

  var
    url = decodeURIComponent( location.search.replace( /^\?q=/, '' ) );

  // storage is keyed on the original url
  browser.storage.local.get( url ).then( function ( o ) {
    var
      html = o[ url ],
      newDOM;

    if ( html ) {
      document.documentElement.textContent = '';
      newDOM = new DOMParser().parseFromString( html, 'text/html' );
      newDOM = newDOM.firstElementChild; // <html>
      while ( newDOM.children.length ) {
        document.documentElement.appendChild( newDOM.firstElementChild );
      }
    } else {
      document.body.textContent =
        'No content found for: ' + url;
    }
  }, function ( err ) {
    document.body.textContent =
      'Error fetching storage: ' + err.name + err.message;
    console.error( err );
  } );
} () );

background.js
中,拦截 Web 请求并将 URL 与已知 URL 进行比较。 (此示例代码仅使用一个 URL,即特定的 YouTube 视频。)如果存在匹配项,则使用原始 URL 作为查询,将 Web 请求重定向到扩展程序。扩展中的 HTML 文档使用查询在存储中查找替换 HTML,然后将其解析并传输到 DOM 中。

对于此示例,设置 URL 的扩展存储(例如,在调试控制台中)并将 HTML 替换为:

browser.storage.local.set( { 'https://www.youtube.com/watch?v=9xp1XWmJ_Wo':
  '<head><title>Stack Overflow Answer</title></head><body><p>This is not a YouTube video.</p></body>' } )

这是

<html>
标签内的所有内容,没有
<html>
标签。无论如何,解析器都会将它们放入,但代码必须将它们丢弃,因为
document.documentElement
无法被替换。

然后前往

https://www.youtube.com/watch?v=9xp1XWmJ_Wo
。相反,会显示替换 HTML。

上面的代码仅适用于主框架中的 HTML,但它证明了这个概念。它依赖于这样一个事实:扩展程序提供的页面中的 JavaScript 以提升的权限运行,因此它可以访问

browser.storage

© www.soinside.com 2019 - 2024. All rights reserved.