谷歌浏览器插件MV3报错Uncaught ReferenceError: window is not defined

更新日期: 2022-11-03 阅读: 2k 标签: 插件

出错

配置mv3后,在后台代码background.js使用domPurify发现无法访问window,会一直报错

Uncaught ReferenceError: window is not defined

查看后台,globalThis变成了一个叫ServiceWorkerGlobalScope的玩意


原因

mv3使用了一个叫Service workers的东西替代原来的background页面,不提供dom api,所以不管是window还是document、htmlElement……都会xx is not defined。
chrome官方介绍:

Manifest V3 replaces background pages with service workers.
Like their web page counterparts, extension service workers listen for and respond to events in order to enhance the end user's experience. For web service workers this typically means managing cache, preloading resources, and enabling offline web pages. While extension service workers can still do all of this, the extension package already contains a bundle of resources that can be accessed offline. As such, extension service workers tend to focus on reacting to relevant browser events exposed by Chrome's extensions APIs.

另附mv2和mv3后台页区别对比表:

MV2 - Background pageMV3 - Service worker
Can use a persistent page.Terminates when not in use.
Has access to the DOM.Doesn't have access to the DOM.
Can use XMLHttpRequest().Must use fetch() to make requests.


解决

1. 放弃在后台页直接调用dom API

chrome官方态度还是比较明确的,所以最好不要花太大力气去搞。能用chrome API的全都用chrome API实现,特别是标签和窗口的操作。另外chrome也提供了一些mv2到mv3迁移的建议migrating_to_service_workers

2. 使用undom模拟

undom是比jsdom轻量的Document接口实现,基本满足dom操作的需求,简单易用。
安装

pnpm install --save undom

使用

import undom from 'undom';
let document = undom();

// 简单操作dom
let foo = document.createElement('foo');
foo.appendChild(document.createTextNode('Hello, World!'));
document.body.appendChild(foo);

// 驱动第三方库DOMPurify
const purify = DOMPurify(document);
purify.sanitize(html..)

另外undom本身不支持直接输出HTML,因为它只实现了Document的骨架,不能直接用innerHTML、querySelector等,提供了手动解析的方法

function serialize(el) {
	if (el.nodeType===3) return el.textContent;
	var name = String(el.nodeName).toLowerCase(),
		str = '<'+name,
		c, i;
	for (i=0; i<el.attributes.length; i++) {
		str += ' '+el.attributes[i].name+'="'+el.attributes[i].value+'"';
	}
	str += '>';
	for (i=0; i<el.childNodes.length; i++) {
		c = serialize(el.childNodes[i]);
		if (c) str += '\n\t'+c.replace(/\n/g,'\n\t');
	}
	return str + (c?'\n':'') + '</'+name+'>';
}

function enc(s) {
	return s.replace(/[&'"<>]/g, function(a){ return `&#${a};` });
}

// 输出完整html
console.log(serialize(document.childNodes[0]));
// 转义html
console.log(enc(serialize(document.childNodes[0])));

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/12232

相关推荐

基于Vue的验证码插件vue2-verify

在我们Web项目开发中,验证码是一种比较常见的区分用户是计算机还是人的手段。主要是为了保证项目的安全。现在Vue开发的项目很多,基本都是前后端分离的。给大家推荐一个基于Vue比较好用的验证码插件vue2-verify。但是大家要注意一点

video.js使用技巧

Video.js初始化有两种方式;一种是在<video>标签里面加上。注意,两者缺一不可。刚开始的时候我觉得后面的值为空对象{},不放也行,导致播放器加载不出来,后来加上来就可以了。

前端最常用的vscode插件集

在前端开发中,使用Visual Studio Code有哪些你常用的插件?推荐几个自己喜欢的,不带链接,自己搜索安装吧。这些都是比较实用、前端必备的插件集

vue开发常用第三方插件总结

这篇文章整理vue开发中常用插件及工具,主要包含: UI组件、开发框架、实用库、服务端SSR、辅助工具、应用实例、Demo示例等,分享给大家,希望对大家有所帮助

浏览器插件_常用谷歌浏览器插件推荐

常用谷谷歌浏览器确实没有其它国产软件的内置功能丰富。但是 Google 浏览器的的优点恰恰就体现在拥有超简约的界面,以及支持众多强大好用的扩展程序,用户能够按照自己的喜好去个性化定制浏览器。今天我就给大家介绍几款自己常用的插件。

对于前端开发,整理推荐好用的chrome插件或应用

向web前端开发者整理提供的chrome插件或应用:比如Postman、JSON Viewer、Page Ruler 、ChromeADB 等等

sublime安装插件

安装Sublime text 2插件很方便,可以直接下载安装包解压缩到Packages目录,也可以安装package control组件,然后直接在线安装

vue项目中使用新手引导功能_intro.js

如何在vue项目中使用用intro.js新手引导功能呢?这里需要使用到vue-introjs插件,vue-introjs是在Vue中绑定intro.js所使用的。在使用vue-introjs前,需要先安装intro.js

使用原生js开发插件的实现方法

作为前端开发,我们都习惯使用一些开源的插件例如jquery工具库,那么如何使用原生js来开发封装一个自己的插件呢?接下来就看一下怎么去开发一个自己的js插件,先上代码

vue项目中vscode格式化配置和eslint配置冲突

使用vscode开发vue项目的时候,从远端拉下一个新的项目后,安装完依赖后跑起项目时,发现直接报了一堆语法错误:包括换行、空格、单双引号、分号等各种格式问题

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!