如何通过Chrome扩展程序将service-worker.js注入网页?我想为现有页面添加离线功能

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

目标: 我想通过 Chrome 浏览器扩展程序向在线网页添加离线功能。

TLDR:

  • [✔️] CSS 注入
  • [✔️]自定义JS注入
  • [✔️] JS 资产来自 通过 declarativeNetRequest 内部重定向的网页
  • [❌] 注射 service-worker.js 在“网站”上,以便 Chrome 可以“离线安装” 渐进式应用”

附加信息

目前状态: 更改任何 CSS 或 JS 都没有问题。它是通过 内容脚本 (https://developer.chrome.com/docs/extensions/mv3/content_scripts/) 完成的。对于额外的 JavaScript 功能,我通过 injector.js 注入额外的脚本 injected.js

injector.js的代码如下所示:

const s = document.createElement("script");
s.src = chrome.runtime.getURL("script-dist.js");
(document.head || document.documentElement).appendChild(s);
s.onload = function () {
  s.parentNode.removeChild(s);
};

在线网站上已有的脚本通过 chrome.declarativeNetRequest (https://developer.chrome.com/docs/extensions/reference/declarativeNetRequest/)“加载时”进行检查,并通过内部重定向交换到准备好的文件副本(代码307)我从网站下载并包含到浏览器扩展中的文件中。

问题: 但这是问题所在。我不知道如何注入“整个”文件。因为渐进式 Web 应用程序 (PWA) 应用程序需要有一个 js 文件作为 service-worker.js,所以我还没有弄清楚如何将其“注入”到当前网站中。我收到的只是跨域资源共享 (CORS) 错误。

这是我想要注入现有页面的 PWA 离线回退模板:https://glitch.com/edit/#!/offline-fallback-demo?path=service-worker.js%3A1%3A0,其中最重要的是 service-worker.jsoffline.html

你会如何解决这个问题?

javascript google-chrome-extension cross-domain progressive-web-apps code-injection
1个回答
0
投票

显然没有直接的方法可以从扩展程序将 js 文件注入到网页,但是您可以使用一种 hack 来替换网页上已存在的 js 文件之一的内容,以便您可以使用它作为服务人员。

它基本上使用 webRequest API,通过它您可以拦截请求并更改来自 Web 扩展的任意响应。

因此,在您尝试将其注册为 Service Worker 并替换 Service Worker 中所需代码的响应后,逻辑将拦截页面中的一个 js 文件。它需要一些权限以及您想要替换响应的网址的主机权限。

它会是这样的:

browser.webRequest.onBeforeRequest.addListener(handleRequest, {urls: ["<all_urls>"], types: ["script"]}, ["blocking"])

function handleRequest(details) {
  const filter = webRequest.filterResponseData(details.requestId)

  let fileText = "";
  filter.ondata = (event) => {
    const buffer = event.data;
    const text = new TextDecoder().decode(buffer);
    fileText += text;
  }

  filter.onstop = () => {
    const replacementText = `console.log("Hello world")
self.addEventListener("fetch", (event) => {
    console.log("fetch event: ", event);
})
`
    const buffer = new TextEncoder().encode(replacementText);
    filter.write(buffer);
    filter.close();

    // Don't forget to do something with the content of the original js file like injecting it somehow.
    console.log(fileText);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.