サイドバーを作成するブラウザー拡張機能を作成します。 Chromeにはファーストクラスのサイドバーがないため、代わりにページにiframeを配置する必要があります。ただし、これはコンテンツセキュリティポリシーにより多くのページで中断されます。GitHubはCSPを使用し、たとえば、capitone.com WebサイトをGitHubのiframeに配置しようとすると、次のようになります。
次のコンテンツセキュリティポリシーディレクティブに違反するため、「 https://www.capitalone.com/ 」のフレーム化を拒否しました:「frame-src 'self' render.githubusercontent.com www.youtube.com asset .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のこの機能により、アドオンまたは拡張機能は、そのスクリプトの生成元に関係なく、Webサイトにスクリプトを挿入できるため、CSPポリシーから免除されます。
私がやっていること以外にiframeを注入する他の方法はありますか?
Chromeに外部iframeを挿入できないことはバグです( crbug.com/408932 )。
外部Webサイトに外部フレームを埋め込む場合は、拡張機能とともにパッケージ化されたフレームに読み込む必要があります。
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"
]
}
使ってはいけません 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);
}
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>
フレームにhttps
サイトをロードしたことを観察することが重要です。フレームにHTTPサイトをロードしようとした場合、混合コンテンツポリシーは、親フレームの1つがhttpsページである場合、フレームのロードをブロックします。
置換https://robwu.nl/
with 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 extension https://github.com/onmyway133/github-chat で正常に動作するようにしました
Chrome 59を使用しているため、ほとんどのES6機能を使用できます。
マニフェストで宣言
"web_accessible_resources": [
"iframe.html",
"scripts/iframe.js"
]
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)
}
あなたの例はChromeで動作するはずですが、現在のところバグのためではありません: https://code.google.com/p/chromium/issues/detail?id=408932 。 Rob Wの回答には、この問題に対する適切な回避策が含まれています。