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

IT技术2年前 (2022)更新 IT大王
0

出错

配置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 page MV3 – 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 += 'nt'+c.replace(/n/g,'nt');
	}
	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])));
© 版权声明
好牛新坐标 广告
版权声明:
1、IT大王遵守相关法律法规,由于本站资源全部来源于网络程序/投稿,故资源量太大无法一一准确核实资源侵权的真实性;
2、出于传递信息之目的,故IT大王可能会误刊发损害或影响您的合法权益,请您积极与我们联系处理(所有内容不代表本站观点与立场);
3、因时间、精力有限,我们无法一一核实每一条消息的真实性,但我们会在发布之前尽最大努力来核实这些信息;
4、无论出于何种目的要求本站删除内容,您均需要提供根据国家版权局发布的示范格式
《要求删除或断开链接侵权网络内容的通知》:https://itdw.cn/ziliao/sfgs.pdf,
国家知识产权局《要求删除或断开链接侵权网络内容的通知》填写说明: http://www.ncac.gov.cn/chinacopyright/contents/12227/342400.shtml
未按照国家知识产权局格式通知一律不予处理;请按照此通知格式填写发至本站的邮箱 wl6@163.com

相关文章