如何在页面加载之前从Chrome devtools扩展中公开功能?

时间:2018-11-19 08:39:01

标签: javascript google-chrome-extension google-chrome-devtools

我正在使用一个Chrome devtools扩展程序,该扩展程序将一个功能(extensionEntryPoint)暴露给检查的页面。问题是extensionEntryPoint在检查的页面加载和运行的初始脚本中不可用。我可以从window.onload使用它,但是为时已晚。

这是我的代码:

manifest.json

{
  "name": "Extension",
  "version": "1",
  "manifest_version": 2,
  "permissions": [
    "activeTab"
  ],
  "web_accessible_resources": ["api.js"],
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content-script.js"],
      "run_at": "document_start",
      "all_frames": true
    }
  ]
}

content-script.js

const script = document.createElement("script");
script.src = chrome.extension.getURL("api.js");
document.documentElement.appendChild(script);

api.js

function extensionEntryPoint(data) {
  console.log("Thanks for calling, I'll debug your data now!")
}

理想情况下,我希望extensionEntryPoint在页面加载时可供页面上的任何脚本使用(例如,在DOMContentLoaded触发之前)。这可能吗?

1 个答案:

答案 0 :(得分:1)

由于quirk/bug in Chrome,目前您的脚本已在其他页面脚本中排队,因此不能保证它是第一个运行的脚本。

解决方案:将api.js的内容放在文字字符串中,并将其分配给script.textContent。
然后,您可以从manifest.json中删除web_accessible_resources。

content-script.js:

const script = document.createElement("script");
script.textContent = `
// the actual contents of api.js
// .......
`;
document.documentElement.appendChild(script);
script.remove();

要在IDE中保留代码的语法高亮显示,请将代码放入函数中,但前提是该代码很小,因为浏览器将不得不执行两次额外的工作,即对该代码进行两次解析并对其进行字符串化。

script.textContent = '(' + (() => {
  // the actual contents of api.js
  // .......
}) + ')()';

如果您在运行代码之前(例如通过node.js)构建代码,则可以编写一个脚本来嵌入api.js的内容,例如在内容脚本中的特殊注释占位符之后。