Chrome 拒绝 <all_urls> 内容脚本注入权限

Chrome denying <all_urls> permission for content script injection

我不确定这是一个错误,还是我的清单文件配置错误,但是 <all_urls> 权限不适用于内容脚本注入。这是一个导致错误的简单示例

manifest.json :

{
  "manifest_version": 2,
  "name": "Bug?",
  "version": "1",
  "description": "This seems to be a bug",
  "minimum_chrome_version": "50",
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  },
   "permissions": [
     "<all_urls>",
     "tabs",
     "webNavigation"
   ]
 }

background.js:

chrome.webNavigation.onBeforeNavigate.addListener(info => {
    chrome.tabs.executeScript(info.tabId, {
        frameId: info.frameId,
        code: 'console.log("works")',
        runAt: 'document_start'
    }, () => {
        if(chrome.runtime.lastError)
            console.error(chrome.runtime.lastError.message)
    })
})

我的objective

我希望我的内容脚本 运行 在浏览器处理页面中的任何 html 和 它的所有子框架 之前。我知道我可以在清单文件中指定我的内容脚本。但是,这并不能让我选择 运行 根框架和子框架的不同内容脚本。因此,上面的代码是我最终代码的一个很好的玩具示例。

实际发生了什么

对于每一帧,内容脚本无法执行并出现以下错误:

Cannot access contents of url "<some url>". Extension manifest must request permission to access this host.

什么?...<all_urls> 不代表 所有 网址?

它的工作原理是什么?

如果我将 chrome.webNavigation.onBeforeNavigate 更改为 chrome.webNavigation.onCommitted,注入将按预期工作(about:blank 页面除外,可以轻松修复)。但是,这并不能保证在处理任何 html 之前我的内容脚本是 运行。

有什么想法吗?

您 运行 陷入了时间问题的混乱局面。

如果您尝试在 onCommitted 发生之前注入,您实际上是在尝试注入 old 文档,因为它还没有改变。

这是一个有根据的猜测,但当您的权限被评估为旧 URL 但到注入实际发生时,可能发生的是竞争条件导航生效,现在原点不同了。

关于 webNavigation/tabs 事件的 run_at: "document_start" 安排的时间不合适。如果您在清单中指定它(或 declarativeContent API 的仍处于实验阶段的内容脚本操作),它只会按照您的意图有效地工作。

现在说说你的问题:

This doesn't, however, let me choose to run a different content script for root and subframes.

这根本不是真的。你可以分支你的逻辑 depending on your position in the iframe hierarchy:

if (window.parent != window) {
  // Subframe
} else {
  // Main frame
}

所以,你应该依赖"document_start"脚本的清单注入,你可以为子帧同步实现不同的逻辑。