Ben*_*ann 39 google-chrome-extension content-security-policy
我想创建一个创建侧边栏的浏览器扩展.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));
Run Code Online (Sandbox Code Playgroud)
然而,根据维基百科,尽管有任何内容安全策略,浏览器扩展应该能够注入iframe:
根据CSP处理模型,[20] CSP不应干扰用户安装的浏览器加载项或扩展的操作.CSP的这一功能有效地允许任何附加组件或扩展程序将脚本注入网站,无论该脚本的来源如何,因此可以免除CSP策略.
除了我正在做的事情之外,还有其他方法可以注入iframe吗?
Rob*_*b W 67
无法在Chrome中插入外部iframe是一个错误(crbug.com/408932).
如果要在外部网站中嵌入外部框架,则必须将其加载到随扩展程序打包的框架中.
manifest.json
{
"name": "Embed external site",
"version": "1",
"manifest_version": 2,
"content_scripts": [{
"js": ["contentscript.js"],
"matches": ["*://*/*"],
"all_frames": true
}],
"web_accessible_resources": [
"frame.html"
]
}
Run Code Online (Sandbox Code Playgroud)
如果希望始终在文档中插入内容脚本,请不要使用chrome.tabs.onUpdated
+ chrome.tabs.executeScript
.您的实现存在缺陷,可能导致脚本多次运行.相反,您应该在清单文件中声明内容脚本.
("all_frames": true
如果您不想在每个子帧中插入帧,请删除.)
contentscript.js
// Avoid recursive frame insertion...
var extensionOrigin = 'chrome-extension://' + chrome.runtime.id;
if (!location.ancestorOrigins.contains(extensionOrigin)) {
var iframe = document.createElement('iframe');
// Must be declared at web_accessible_resources in manifest.json
iframe.src = chrome.runtime.getURL('frame.html');
// Some styles for a fancy sidebar
iframe.style.cssText = 'position:fixed;top:0;left:0;display:block;' +
'width:300px;height:100%;z-index:1000;';
document.body.appendChild(iframe);
}
Run Code Online (Sandbox Code Playgroud)
frame.html
<style>
html, body, iframe, h2 {
margin: 0;
border: 0;
padding: 0;
display: block;
width: 100vw;
height: 100vh;
background: white;
color: black;
}
h2 {
height: 50px;
font-size: 20px;
}
iframe {
height: calc(100vh - 50px);
}
</style>
<h2>Displaying https://robwu.nl in a frame</h2>
<iframe src="https://robwu.nl/"></iframe>
Run Code Online (Sandbox Code Playgroud)
重要的是观察我https
在框架中加载了一个站点.如果您尝试在帧中加载HTTP站点,则混合内容策略将阻止在父帧之一是https页面时加载帧.
替换https://robwu.nl/
为http://example.com/
,https://github.com等https页面上的框架将保持空白.同时,以下消息将打印到控制台.
[blocked] The page at 'https://github.com/' was loaded over HTTPS, but ran insecure content from 'http://example.com/': this content should also be loaded over HTTPS
Rob W 的回答是正确的。您可以按照此https://transitory.technology/browser-extensions-and-csp-headers/ 进行操作。我已经成功地让它在我的 Chrome 扩展中工作了https://github.com/onmyway133/github-chat
请注意,我使用的是 Chrome 59,因此可以使用大部分 ES6 功能
在清单中声明
"web_accessible_resources": [
"iframe.html",
"scripts/iframe.js"
]
Run Code Online (Sandbox Code Playgroud)
在 window.onload 事件中创建一个 iframe
let url = decodeURIComponent(window.location.search.replace('?url=', ''))
let iframe = document.createElement('iframe')
iframe.src = url
iframe.id = 'github-chat-box-iframe-inner'
iframe.style.width = '100%'
iframe.style.height = '350px'
iframe.style.border = '0px'
window.onload = () => {
document.body.appendChild(iframe)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
35916 次 |
最近记录: |