问题描述
使用 manifest v2 可以正常工作。但是使用 manifest v3 我收到错误“ReferenceError: localStorage is not defined”
manifest.json
{
"name": "Getting Started Example","description": "Build an Extension!","version": "1.0","manifest_version": 3,"background": {
"service_worker": "background.js"
},"permissions": ["storage","activeTab","contextMenus"],"action": {
"default_popup": "popup.html"
}
}
背景.js
var contextMenuItems = {
"title": 'Add to notepad"',"contexts": ["selection"],"id": "myContextMenuId"
};
chrome.contextMenus.create(contextMenuItems);
chrome.contextMenus.onClicked.addListener(function(clickData){
if(clickData.menuItemId == "myContextMenuId" && clickData.selectionText){
localStorage.setItem("text","clickData.selectionText");
}
});
解决方法
ManifestV3 中的后台脚本现在是 service worker
,因此它无法访问仅在 window
上公开的内容,例如 HTML5 localStorage 或 DOM。顺便说一下,Service Worker 没有 window
,它们的全局上下文是 self
或 globalThis
。
解决办法是切换到chrome.storage.local。这是一种完全不同的存储,可用于所有扩展上下文,包括内容脚本。请注意,a) 它是异步的,因此用法不同;b) 由于 bug in Chrome,它当前不返回 Promise,因此您不能 await
它。在修复之前,请使用文档中显示的回调版本。
存储:
chrome.contextMenus.onClicked.addListener(info => {
if (info.menuItemId == 'myContextMenuId' && info.selectionText) {
chrome.storage.local.set({text: info.selectionText});
}
});
在弹出窗口中阅读:
chrome.storage.local.get('text',({text}) => {
// the callback runs asynchronously so you should use the value here
document.body.prepend(text);
});