从扩展程序中访问网页的`window`/DOM/HTML
P粉046878197
P粉046878197 2023-10-18 09:44:00
0
2
477

我正在编写一个 Chrome 扩展程序,并尝试在 popup.html 文件中单击按钮后立即在当前网页上覆盖

当我从 popup.html 中访问document.body.insertBefore方法时,它会覆盖弹出窗口上的

,而不是当前网页。

我是否必须在background.html 和popup.html 之间使用消息传递才能访问网页的DOM?我想在 popup.html 中完成所有操作,并且如果可能的话也使用 jQuery。

P粉046878197
P粉046878197

全部回复 (2)
P粉296080076

使用编程注入来添加该 div 的扩展弹出脚本的一些示例。

清单V3

不要忘记在manifest.json中添加权限,请参阅其他答案以获取更多信息。

  • 简单调用:

    (async () => { const [tab] = await chrome.tabs.query({active: true, currentWindow: true}); await chrome.scripting.executeScript({ target: {tabId: tab.id}, func: inContent1, }); })(); // executeScript runs this code inside the tab function inContent1() { const el = document.createElement('div'); el.style.cssText = 'position:fixed; top:0; left:0; right:0; background:red'; el.textContent = 'DIV'; document.body.appendChild(el); }

    注意:在 Chrome 91 或更早版本中,func:应为function:

  • 使用参数调用并接收结果

    需要 Chrome 92,因为它实现了args

    示例1:

    res = await chrome.scripting.executeScript({ target: {tabId: tab.id}, func: (a, b) => { return [window[a], window[b]]; }, args: ['foo', 'bar'], });

    示例2:

    (async () => { const [tab] = await chrome.tabs.query({active: true, currentWindow: true}); let res; try { res = await chrome.scripting.executeScript({ target: {tabId: tab.id}, func: inContent2, args: [{ foo: 'bar' }], // arguments must be JSON-serializable }); } catch (e) { console.warn(e.message || e); return; } // res[0] contains results for the main page of the tab document.body.textContent = JSON.stringify(res[0].result); })(); // executeScript runs this code inside the tab function inContent2(params) { const el = document.createElement('div'); el.style.cssText = 'position:fixed; top:0; left:0; right:0; background:red'; el.textContent = params.foo; document.body.appendChild(el); return { success: true, html: document.body.innerHTML, }; }

清单V2

  • 简单调用:

    // uses inContent1 from ManifestV3 example above chrome.tabs.executeScript({ code: `(${ inContent1 })()` });
  • 使用参数调用并接收结果:

    // uses inContent2 from ManifestV3 example above chrome.tabs.executeScript({ code: `(${ inContent2 })(${ JSON.stringify({ foo: 'bar' }) })` }, ([result] = []) => { if (!chrome.runtime.lastError) { console.log(result); // shown in devtools of the popup window } });

    此示例使用inContent函数的代码自动转换为字符串,这样做的好处是 IDE 可以应用语法突出显示和 linting。明显的缺点是浏览器会浪费时间来解析代码,但通常不到 1 毫秒,因此可以忽略不计。

    P粉600402085

    问题:扩展页面(弹出窗口、选项、MV2 中的背景页面等)与网页分离,它们有自己的 DOM、document、window 和chrome-extension://URL。

    解决方案:使用内容脚本访问网络页面或与其内容交互。

    • 内容脚本在网页中执行,而不是在扩展程序中执行。
    • 内容脚本默认是隔离的,请参阅如何在页面上下文中运行代码(也称为主世界)。
    • 不要在扩展程序页面中加载内容脚本。

    方法1.声明式

    manifest.json:

    "content_scripts": [{ "matches": ["*://*.example.com/*"], "js": ["contentScript.js"] }],

    它将在页面加载时运行一次。之后,请使用消息传递

    警告!它不能发送 DOM 元素、Map、Set、ArrayBuffer、类、函数等。它只能发送与 JSON 兼容的简单对象和类型,因此您需要手动提取所需的数据并将其作为简单数组或对象传递。

    方法 2. 程序化

    • ManifestV3

      在扩展脚本(如弹出窗口)可根据需要将内容脚本/函数注入选项卡。

      此方法的结果是内容脚本中的最后一个表达式,因此可用于提取数据。数据必须与 JSON 兼容,请参阅上面的警告。

      manifest.json 中所需的权限

      • “脚本”- 强制;
      • "activeTab"- 理想场景,适合对用户操作的响应(通常是单击工具栏中的扩展图标)。安装扩展程序时不显示任何权限警告。

      如果理想情况不可能,请将允许的站点添加到manifest.json 中的host_permissions

      • “*://*.example.com/”以及您想要的任何其他网站。

      • " " "*://*/"这些会将您的扩展程序置于 Chrome 网上应用店中超慢审核队列中由于广泛的主机权限。

    • ManifestV2 与上述的差异:

      最新下载
      更多>
      网站特效
      网站源码
      网站素材
      前端模板
      关于我们 免责声明 Sitemap
      PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!