如何在Google Chrome扩展程序中使用服务工作器(Service Workers)修改HTTP响应体?

8
现在Google Chrome扩展程序可以注册Service Workers,那么我该如何使用它们来修改所有主机的HTTP响应,例如将所有出现的cat替换为dog
以下是Craig Russell的示例代码,但如何在Chrome扩展程序中使用它并将其绑定到所有主机?
self.addEventListener('fetch', function(event) {
    event.respondWith(
        fetch(event.request).then(function(response) {
            var init = {
                status:     response.status,
                statusText: response.statusText,
                headers:    {'X-Foo': 'My Custom Header'}
            };
            response.headers.forEach(function(v,k) {
                init.headers[k] = v;
            });
            return response.text().then(function(body) {
                return new Response(body.replace(/cat/g, 'dog'), init);
            });
        })
    );
});

似乎无法工作,我收到了错误消息“Add / AddAll不支持除“http”或“https”之外的方案”,该错误出现在缓存cache.addAll(urlsToCache)上。 - Pacerier
这里有很多关于cache.addAll的结果:https://www.google.com/search?q=cache.addAll,但似乎没有一个教程是针对Chrome扩展程序的... - Pacerier
serviceworker 中的 chrome 对象很奇怪。无法使用 chrome.tabs - Pacerier
好的,在一些尝试和错误之后,我已经部分地拼凑出来了。我已经发布了一个答案,请见下文。顺便说一句,我认为这里不需要“cache” API。 - Pacerier
有关跨源ServiceWorker,请参见 https://stackoverflow.com/q/46760820/632951 - Pacerier
1个回答

1
解决方案。

≪manifest.json≫:

{"manifest_version":2,"name":"","version":"0","background":{"scripts":["asd"]}}

≪asd≫:

navigator.serviceWorker.register('sdf.js').then(x=>console.log('done', x))

≪sdf.js≫:

addEventListener('fetch', e=> e.respondWith(fetch/*btw xhr is undefined*/(e.request).then(r=>{
  if(r.headers === undefined /*request not end with <.htm>, <.html>*/){}else{
    console.assert(r.headers.get('content-type')===null)/*for some odd reason this is empty*///[
      let h = new Headers()
      r.headers.forEach((v,k)=>h.append(k,v))
      Object.defineProperty(r,'headers',{'writable':true})
      r.headers = h
      r.headers.append('content-type','text/html'/*btw <htm> doesnt work*/)
    //]
  }
  return r.text().then(_=>new Response(_.replace(/cat/g,'dog'),r))
})))

前往≪页面网址≫(≪chrome-extension://≪扩展程序id≫/≪页面路径≫≫),查看替换内容。


独立响应

≪manifest.json≫和≪asd≫与上述相同。

≪sdf.js≫:

addEventListener('fetch', e=> e.respondWith(new Response('url: '+e.request.url,{headers:{'content-type':'text/html'/*, etc*/}})))


顺便提一下

Service Worker 还有其他事件可以深入了解,例如:

addEventListener('message', e=>{
  console.log('onmessage', e)
})
addEventListener('activate', e=>{
  console.log('onactivate', e)
})
addEventListener('install', e=>{
  console.log('oninstall', e)
})


替代方案

请注意,目前serviceworker [–cf webNavigation, webRequest]是唯一的方法,因为Google开发团队中的某些人决定,对于响应修改的webNavigation和webRequest来说它是“不安全”的。


注意

Chrome错误:

  • 扩展程序≪重新加载≫将无法重新加载serviceworkers。您需要删除该扩展程序并重新加载它。
  • 页面刷新无效,即使使用chrome devtools禁用缓存硬刷新也无效。请使用正常的页面访问。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接