我想创建一个创建侧边栏的浏览器扩展 . Chrome没有一流的侧边栏,因此我们必须在页面中添加iframe . 但是,由于内容安全策略,这会在许多页面上中断 . 例如 . GitHub使用CSP,它不允许嵌入来自其他网站的iframe . 例如 . 如果您尝试将capitalone.com网站放在GitHub上的iframe中,您将获得以下内容:
拒绝框架'https://www.capitalone.com/',因为它违反了以下内容安全政策指令:“frame-src'self'recrera.githubusercontent.com www.youtube.com assets.braintreegateway.com” .
这是一个简单的浏览器扩展,可以重现:
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (changeInfo.status === 'complete') {
chrome.tabs.executeScript(tabId, { code: 'document.body.innerHTML=\'<iframe style=\"width:600px; height:600px\" src=\"https://www.capitalone.com/\"></iframe>\' + document.body.innerHTML;' }, function() {
console.log('Iframe injection complete');
})
}
}.bind(this));
然而,根据维基百科,尽管有任何内容安全策略,浏览器扩展应该能够注入iframe:
根据CSP处理模型,[20] CSP不应干扰用户安装的浏览器插件或扩展的操作 . CSP的这一功能有效地允许任何附加组件或扩展程序将脚本注入网站,无论该脚本的来源如何,因此可以免除CSP策略 .
除了我正在做的事情之外,还有其他方法可以注入iframe吗?
3 回答
无法在Chrome中插入外部iframe是一个错误(crbug.com/408932) .
如果要在外部网站中嵌入外部框架,则必须将其加载到随扩展程序打包的框架中 .
manifest.json
如果希望始终在文档中插入内容脚本,请勿使用
chrome.tabs.onUpdated
chrome.tabs.executeScript
. 您的实现存在缺陷,可能导致脚本多次运行 . 相反,你应该declare the content script in the manifest file .(如果您不想在每个子帧中插入帧,请删除
"all_frames": true
. )contentscript.js
frame.html
重要的是要注意我在框架中加载了一个
https
站点 . 如果您尝试在框架中加载HTTP站点,则混合内容策略将阻止加载帧,如果其中一个父帧是https页面 .将
https://robwu.nl/
替换为http://example.com/
,并且该帧将在https页面上保持空白,例如https://github.com . 同时,以下消息将打印到控制台 .Rob W的回答是正确的 . 你可以按照这个https://transitory.technology/browser-extensions-and-csp-headers/ . 我已成功将其在Chrome扩展程序中运行https://github.com/onmyway133/github-chat
请注意,我使用Chrome 59,因此我可以使用大多数ES6功能
Declare in manifest
Create an iframe in window.onload event
您的示例应该可以在Chrome中使用,但它目前不会因为一个错误:https://code.google.com/p/chromium/issues/detail?id=408932 . Rob W的答案包含了解决该问题的良好解决方案 .