悪意のあるスクリプトがポップアップなどの機密性の高い API を悪用するのを防ぐには、 ブラウザは、ユーザー コンテンツを介してこれらの API へのアクセスを制御します。 支援しますユーザーのアクティベーションとは、以下に関するブラウジング セッションの状態を指します。 ユーザー アクションに結び付けられます。つまり、状態とは、通常、ユーザーが状態を失うか、 ユーザーが現在そのページを操作している、またはページ上で操作を完了したユーザー 負荷を軽減できます。「ユーザー ジェスチャー」は、同じ考え方に対してよく使われている用語ですが、誤解を招くおそれもあります。対象 たとえば、ユーザーがスワイプやフリックのジェスチャーを行ってもページはアクティブにならず、 スクリプトの観点からはユーザーの アクティベーションではありません
昨今の主要なブラウザでは、ユーザーの有効化の仕組みが大きく異なる
アクティベーション ゲート型 API を制御します。Chrome での実装は、
トークンベースのモデルは複雑すぎて、一貫性のある
動作を調整する必要があります。たとえば、Chrome は
API への不完全なアクセスを許可するため、
postMessage()
、
setTimeout()
呼び出し。ユーザーアクティベーションは
Promise のサポート
XHR、
ゲームパッド操作など。ただし、
昔からある虫です。
バージョン 72 の Chrome には User Activation v2 が付属しており、 アクティベーションの空き状況の確認が完了しました。これにより、 前述の不整合を解消し、 MessageChannels)を 開発に集中できますさらに新しい実装では 提案するソリューションのリファレンス実装を 新しい仕様 長い目で見れば、すべてのブラウザを統合することを目指しています。
ユーザー アクティベーション v2 の仕組み
新しい API は、window
オブジェクトごとに 2 ビットのユーザー アクティベーション状態を維持します。
(フレーム階層内の過去のユーザーのアクティベーション状態を表すスティッキー ビット)。
(ユーザーのアクティベーションを確認したことのある))と現在の状態の一時的なビット
(フレームが約 1 秒後にユーザーのアクティベーションを確認した場合)。スティッキー ビット
設定後のフレームの存続期間中にリセットされることはありません。一時的なビット
ユーザー操作のたびに設定され、有効期限が切れるか、
またはアクティベーションを使用する API の呼び出しによって行うか
(例: window.open()
)。
アクティベーション ベース型 API は、ユーザー アクティベーションに依存する別の API です。
方法これらの API 固有の動作は、新しい API によって変更されることはありません。例:
window.open()
が消費するため、有効化できるポップアップは 1 ユーザーにつき 1 つのみです
以前のようにユーザー アクティベーションを行えば、Navigator.prototype.vibrate()
は
フレーム(またはそのサブフレームのいずれか)がユーザー アクションを確認したことがある場合に有効である。
といった具合です
変更内容
- User Activation v2 は、ユーザー アクティベーションの可視性の概念を形式化しました。 フレーム境界を越えます。特定のフレームに対するユーザー インタラクションは、 そのフレームが含まれているすべてのフレームを 含まれます。(Chrome 72 では、一時的な回避策として すべての同一オリジン フレームに対する可視性が向上します。この回避策は、 新しいテクノロジーを ユーザーのアクティベーションをサブフレームに明示的に渡す)。
- 有効化の制限された API が有効化されたフレームから呼び出されても、 イベント ハンドラ コードの外部では、ユーザーが有効にしている限り、 ステータスが「アクティブ」(例: 有効期限が切れていない、または使用されていない)。使用前 アクティベーション v2 の場合は、無条件に失敗します。
- 有効期限内の複数の未使用のユーザー操作が融合します 最後のインタラクションに対応する 1 つのアクティベーションに統合します。
アクティベーション ゲート型 API における整合性の例
ポップアップ ウィンドウ(window.open()
を使用して開きます)の 2 つの例を示します。
User Activation v2 が、有効化ゲート型 API の動作を実現する仕組み
必要があります。
setTimeout()
通話のチェーン
この例では
setTimeout()
のデモをご覧ください。
click
ハンドラが 1 秒以内にポップアップを開こうとすると、
コードがどのように「構成」されてもできます。User Activation v2 は、
そのため、以下の各イベント ハンドラでは、イベントに応じたポップアップが
click
(100 ミリ秒の遅延):
function popupAfter100ms() {
setTimeout(callWindowOpen, 100);
}
function asyncPopupAfter100ms() {
setTimeout(popupAfter100ms, 0);
}
someButton.addEventListener('click', popupAfter100ms);
someButton.addEventListener('click', asyncPopupAfter100ms);
ユーザー アクティベーション v2 がなければ、2 番目のイベント ハンドラはすべてのブラウザで失敗します。 検証できます。(最初のテストで 場合によります)。
クロスドメインの postMessage()
呼び出し
この例は、
postMessage()
のデモをご覧ください。
クロスオリジン サブフレーム内の click
ハンドラが 2 つのメッセージを直接送信するとします。
親フレームに追加してください親フレームは、起動時にポップアップを表示できるようにする必要があります。
次のいずれかのメールを受信します(両方は不可)。
// Parent frame code
window.addEventListener('message', e => {
if (e.data === 'open_popup' && e.origin === child_origin)
window.open('about:blank');
});
// Child frame code:
someButton.addEventListener('click', () => {
parent.postMessage('hi_there', parent_origin);
parent.postMessage('open_popup', parent_origin);
});
ユーザー アクティベーション v2 がない場合、親フレームは受信時にポップアップを開けません 表示されます。「チェーン」になっていると最初のメッセージでも失敗する別の (つまり、最初の受信者がメッセージを転送した場合、 など)。
これは、ユーザー アクティベーション v2 で、元の形式と チェーン化します。