Chrome 扩展:DOMParser 未在 Manifest v3 中定义

Lau*_*ent 10 google-chrome-extension chrome-extension-manifest-v3

我开发了一个扩展来从网页上抓取一些内容,到目前为止它工作正常,但自从我切换到清单 v3 后,解析不再工作。

我使用以下脚本来读取源代码:

chrome.scripting.executeScript( 
  {
    target: {tabId: tab.id, allFrames: true},
    files: ['GetSource.js'],
  }, async function(results) 
  {
    // GETTING HTML
    parser = new DOMParser();
    content = parser.parseFromString(results, "text/html");
Run Code Online (Sandbox Code Playgroud)

... ETC ... 该代码曾经工作正常,但现在我在控制台中收到以下消息:

未捕获(承诺中)ReferenceError:DOMParser 未定义

代码是承诺的一部分,但我不认为承诺是这里的问题。我基本上需要将源代码加载到变量中,以便之后可以解析它。

我检查了文档,但没有发现 DOMParser 不适用于 v3 的内容。

任何想法?

谢谢

Nin*_*ham 6

来自文档

由于 Service Worker 无权访问 DOM,因此扩展的 Service Worker 无法访问 DOMParser API 或创建解析和遍历文档。

使用外部库只是为了做DomParser已经做的事情?它太重了。

为了解决这个问题,我们可以使用offscreen文档。它只是一个不可见的网页,您可以在其中运行fetchaudioDomParser、 ... 并通过 与后台(service_worker)通信chrome.runtime

请参阅下面的示例:

背景.js

// create (load) the offscreen document (xam.html)
chrome.offscreen.createDocument({
    url: chrome.runtime.getURL('xam.html'),
    reasons: [chrome.offscreen.Reason.DOM_PARSER],
    justification: 'reason for needing the document',
});

// This is simply a test.
// It represents a scenario where, after three seconds, you want to fetch a webpage and extract HTML.
// Once the three seconds have elapsed, we send a 'broadcast' out to the listeners of our extension.
// The listener in the offscreen document will handle the job and send back us with its resulting data.

setTimeout(() => {
    const onDone = (result) => {
        console.log(result);
        chrome.runtime.onMessage.removeListener(onDone);
    };
    chrome.runtime.onMessage.addListener(onDone);
    chrome.runtime.sendMessage('from-background-page');
}, 3000);

Run Code Online (Sandbox Code Playgroud)

xam.html

<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script src="xam.js">
  </script>
</body>

</html>
Run Code Online (Sandbox Code Playgroud)

xam.js

async function main() {
    const v = await fetch('https://......dev/').then((t) => t.text());
    const d = new DOMParser().parseFromString(v, 'text/html');
    const options = Array.from(d.querySelector('select').options)
        .map((v) => `${v.value}|${v.text}`)
        .join('\n');
    chrome.runtime.sendMessage(options);
}

chrome.runtime.onMessage.addListener(async (msg) => {
    console.log(msg);
    main();
});
Run Code Online (Sandbox Code Playgroud)

清单.json

  "permissions": [
    // ...
    "offscreen"
  ]
Run Code Online (Sandbox Code Playgroud)

https://developer.chrome.com/docs/extensions/reference/offscreen/

该扩展程序的权限可以转移到屏幕外的文档,但扩展程序 API 访问受到严重限制。目前,离屏文档只能使用 chrome.runtime API 来发送和接收消息;所有其他扩展 API 均不公开。

笔记:

  • 我还没有测试过这个文件的存活时间offscreen
  • 只是示例代码,它应该可以工作。Customzie 作为您自己的案例。


小智 0

由于 Service Worker 无权访问 DOM,因此扩展的 Service Worker 无法访问 DOMParser API 或创建

解析和遍历文档。

更多详情

我通过使用库 dom-parser 解决了这个问题。代码可能是这样的

import DomParser from "dom-parser";
const parser = new DomParser();
const dom = parser.parseFromString('you html string');
Run Code Online (Sandbox Code Playgroud)