目标: 我想通过 Chrome 浏览器扩展程序向在线网页添加离线功能。
TLDR:
目前状态: 更改任何 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.js 和 offline.html
你会如何解决这个问题?
显然没有直接的方法可以从扩展程序将 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);
}
}