Chrome扩展标签页注入JS出现"Cannot access contents of url"报错求助
解决Chrome扩展注入JS到新标签页的权限问题
这个问题我之前也踩过坑,核心原因是Chrome的默认新标签页(包括你遇到的那个https://www.google.com/_/chrome/newtab...)属于特殊内部页面范畴,普通的*://*/*权限根本覆盖不了这类页面,哪怕你已经在manifest里加了这个权限也没用。
问题拆解
Chrome把默认新标签页(不管是原生的chrome://newtab还是Google定制的伪装域名版本)当作特殊内部页面处理,这类页面的权限需要单独声明;而且你用tabs.onCreated触发注入的时机太早,标签页还没完成初始化,很容易触发权限校验失败。
具体解决方案
1. 补充必要的权限到manifest
根据你用的manifest版本(v2或v3),添加对应的权限:
- 如果是Manifest V3:
{ "manifest_version": 3, "permissions": ["tabs", "scripting", "chrome://newtab/"], "host_permissions": [ "*://*/*", "https://www.google.com/_/chrome/newtab/*" ] } - 如果是Manifest V2:
{ "manifest_version": 2, "permissions": [ "tabs", "*://*/*", "chrome://newtab/", "https://www.google.com/_/chrome/newtab/*" ] }
这里额外加了chrome://newtab/特殊权限,以及你遇到的那个具体Google新标签页的域名权限,确保覆盖所有可能的新标签页场景。
2. 调整注入时机与逻辑
tabs.onCreated触发时标签页还在初始化,此时注入很容易报错。建议改用tabs.onUpdated监听,等页面进入loading状态后再注入,同时过滤目标页面:
// Manifest V3 写法 chrome.tabs.onUpdated.addListener(async (tabId, changeInfo, tab) => { // 匹配新标签页的URL模式 const isNewTab = tab.url.startsWith('chrome://newtab/') || tab.url.startsWith('https://www.google.com/_/chrome/newtab/'); // 确保页面处于加载状态且是目标页面 if (changeInfo.status === 'loading' && isNewTab) { try { await chrome.scripting.executeScript({ target: { tabId: tabId }, files: ['executeScript.js'] }); console.log('脚本注入成功'); } catch (err) { console.error('注入失败:', err); } } }); // 如果是Manifest V2,写法如下: /* chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { const isNewTab = tab.url.startsWith('chrome://newtab/') || tab.url.startsWith('https://www.google.com/_/chrome/newtab/'); if (changeInfo.status === 'loading' && isNewTab) { chrome.tabs.executeScript(tabId, { file: 'executeScript.js' }, (result) => { if (chrome.runtime.lastError) { console.error('注入失败:', chrome.runtime.lastError); } else { console.log('脚本注入成功'); } }); } }); */
3. 额外稳定方案(可选)
如果上述方案还是偶尔出问题,可以考虑覆盖默认新标签页:在manifest里添加以下配置,用自己的页面替换原生新标签页,再在自定义页面里直接引入脚本,这种方式权限限制最少:
// Manifest V3/V2 通用 "chrome_url_overrides": { "newtab": "my_newtab.html" }
然后在my_newtab.html里直接引入你的脚本:
<script src="executeScript.js"></script>
内容的提问来源于stack exchange,提问作者debanjan mal
相关产品推荐
相关产品推荐

