WebブラウザはiframeのJavaScriptに個別の実行スレッドを使用しますか?
Chromeはタブごとに別々のスレッドを使用していると思うので、iframe内のJavaScriptはその親ウィンドウと同じスレッドを共有すると思いますが、それもセキュリティ上のリスクのようです。
WebブラウザはiframeのJavaScriptに個別の実行スレッドを使用しますか?
Chromeはタブごとに別々のスレッドを使用していると思うので、iframe内のJavaScriptはその親ウィンドウと同じスレッドを共有すると思いますが、それもセキュリティ上のリスクのようです。
最近、iFrameで実行されているJavaScriptが親ウィンドウでのJavaScriptの実行をブロックするかどうかをテストしました。
親と同じドメインのiFrame:
親として別のドメインのiFrame
chrome://process-internals
してくださいchrome://flags
)parent.html:
<body>
<div id="count"></div>
<iframe src="./spin.html"></iframe>
<script>
let i = 0;
let div = document.getElementById("count");
setInterval(() => {
div.innerText = i++;
}, 100);
</script>
</body>
spin.html:
<body>
<button id="spin">spin</button>
<script>
const spin = document.getElementById("spin");
spin.addEventListener('click', () => {
const start = Date.now();
while (Date.now() - start < 1000) { }
})
</script>
</body>
Chromeが登場する前は、どのブラウザのすべてのタブも同じJavaScriptの単一スレッドを共有していました。Chromeはここでゲームを強化し、他の何人かはそれ以来それに続いています。
これはブラウザの実装の詳細であるため、確実な答えはありません。古いブラウザは間違いなくそうではありません。iframeに別のスレッドを確実に使用しているブラウザは知りませんが、正直なところ、実際に調べたことはありません。
スレッドの実行に伴ってオブジェクトが持ち込まれないため、セキュリティ上のリスクはありません。
他の答えを要約すると:いいえ、iFrameは通常メインページと同じスレッド/プロセスで実行されます。
ただし、Chromiumチームはこの分野でさらなる隔離に取り組んでいるようです。
Chromium Issue 99379:プロセス外のiframe [申し訳ありませんが、リンクが機能していません-機能する問題へのリンクが見つかった場合は、お知らせください]
私は今夜、既存の答えをチェックする前に、同じ質問をしました。私が現在取り組んでいるプロジェクトでは、別のフレームワークを使用するiFrameをロードする必要があり、そのiFrameが何らかの形でスレッドをブロックしてアプリに影響を与える可能性があるかどうかは好奇心旺盛でした。答えはイエスです、それは可能です。
私のテストはChromeで行われました。親に子iFrameをロードしました。親では、毎回テキストをconsole.logに記録する間隔を設定しました。次に、iFrameでタイムアウトを使用して、スレッドをブロックする「while」を起動しました。答え:iFrameは同じスレッドを使用します。
例:
親の場合:
setInterval(() => {
console.log('iFrame still using the thread');
}, 3000)
iFrameの場合:
setTimeout(() => {
console.log('now the thread is not working in the iFrame anymore');
while (true) {
}
}, 10000)
デスクトップ(モバイルではなく)上のchromeとfirefoxのみがスレッドを分離しています。
メインページで間隔を空けて長いループを実行し、メインページとiframeの両方にアニメーションを表示する小さなページを作成しました。確認したいブラウザからサイトにアクセスできます。
下のアニメーション(「クロスオリジン」の下)が停止せずに実行される場合は、別のスレッドがあります。
これは遅いですが...良い点です。Firefox16ではiframejsが同時実行されているようです。
アラート機能(ブロック)を試してみると、ダイアログが一緒に開いているのがわかります。
ChromeやIEでは表示されません。
iframejsは通常どおりFirefox16の親ウィンドウにアクセスする可能性があるため、競合状態が発生する可能性があると考えられます。
今日、UbuntuのChrome28でこれを試してみました。このコマンドを使用して、Chromeのスレッドとプロセスを確認しました
ps axo pid,nlwp,cmd | grep "chrome"
Chromeはiframeの新しいスレッドやプロセスを生成しないようです。興味深いことに、開発ツールペインに新しいプロセスが生成されます。
Origin-Agent-Cluster
iframe専用のリソースをリクエストできるヘッダーが追加されました。現在、Chrome(88+)でサポートされており、MozillaとSafariから好評を得ています。
Origin-Agent-Clusterは、同じサイトのクロスオリジンページ間の同期スクリプトアクセスを防ぐようにブラウザに指示する新しいHTTP応答ヘッダーです。ブラウザは、オリジンが専用プロセスなどの独自の個別のリソースを取得する必要があることを示すヒントとして、Origin-Agent-Clusterを使用する場合もあります。
[...]たとえば、
https://customerservicewidget.example.com
ビデオチャットに多くのリソースを使用することが予想され、全体のさまざまなオリジンに埋め込まれる場合https://*.example.com
、そのウィジェットを維持するチームは、Origin-Agent-Clusterヘッダーを使用して、パフォーマンスへの影響を減らすことができます。埋め込み。
Origin-Agent-Clusterヘッダーを使用するには、次のHTTP応答ヘッダーを送信するようにWebサーバーを構成します。
Origin-Agent-Cluster: ?1
の値?1
は、ブール値のtrue値の構造化ヘッダー構文です。
Iframeは、デスクトップコンピューターの少なくともChrome Canaryで並行して実行できるようになりましたが、これはまだ実験段階です。
<h1>index.html</h1>
<iframe src="index-child.html" sandbox="allow-scripts"></iframe>
<script>
setInterval(() => {
console.log("index.html executed one iteration");
}, 1000)
</script>
<h1>index-child.html</h1>
<script>
setTimeout(() => {
console.log("index-child.html started continuous execution");
while (true) {
}
}, 3000)
</script>
注:これを機能さsandbox
せるには、タグの属性をiframe
正しく設定する必要があります。さらに、現在サポートされている追加のプロセスはサイトごとに1つだけです。つまり、複数のiframeがすべて並行して実行されるわけではありません。
「chrome:// flags /」からの具体的な手順:
分離されたサンドボックス化されたiframe
有効にすると、「sandbox」属性があり、その属性に「allow-same-origin」権限が設定されていないiframeにプロセス分離が適用されます。現在の分離モデルでは、特定のサイトのすべてのサンドボックス化されたiframeが同じプロセスに配置されますが、将来の実験で代替モデルが導入される可能性があります。– Mac、Windows、Linux、Chrome OS、Fuchsia
iFrameの場合、いいえ。ただし、JavaScriptでスレッドを使用する場合は、新しいブラウザーでサポートされているhtml5ドラフトであるWebワーカーを使用できます。http://www.w3.org/TR/2009/WD-workers-20091029/