サンドボックスページ
サンドボックスページは、異なるCSP(コンテンツセキュリティポリシー)制限を持つ特別な拡張機能ページです。例えば、サンドボックスページ内では任意のコードをeval
することが可能です。拡張機能ページと比較してより多くの権限を持つ安全なコンテキストでコードを動的に実行するために、サンドボックスページを使用します。
サンドボックスページは、CSUIと同様にUIコンポーネントをマウントしたり、単純なスクリプトを実行したりできます。次の例では、サンドボックスページから任意のコードをeval
し、メッセージパッシングを介して結果を呼び出し元に送り返す機能を示しています。
まず、サンドボックスページを追加します。
- ソースディレクトリ(プロジェクトルートまたは
src
)にsandbox.ts
ファイルまたはsandboxes/<name>.ts
ファイルを作成します。 - 次のスクリプトをエクスポートします。
sandbox.ts
export const life = 42
window.addEventListener("message", async function (event) {
const source = event.source as {
window: WindowProxy
}
source.window.postMessage(eval(event.data), event.origin)
})
上記のスクリプトは、ウィンドウスコープからのmessage
イベントをリッスンし、data
プロパティを介して呼び出し元から送信されたコードをeval
します。サンドボックスページは、拡張機能バンドル内のsandbox.html
またはsandboxes/<name>.html
で利用可能になります。このページにメッセージを送信するには、iframe内にマウントし、postMessage APIを呼び出す必要があります。popup.tsx
拡張機能ページで実行してみましょう。
popup.tsx
import { useEffect, useRef, useState } from "react"
function IndexPopup() {
const iframeRef = useRef<HTMLIFrameElement>(null)
useEffect(() => {
window.addEventListener("message", (event) => {
console.log("EVAL output: " + event.data)
})
}, [])
return (
<div
style={{
display: "flex",
flexDirection: "column",
padding: 16
}}>
<button
onClick={() => {
iframeRef.current.contentWindow.postMessage("10 + 20", "*")
}}>
Trigger iframe eval
</button>
<iframe src="sandbox.html" ref={iframeRef} style={{ display: "none" }} />
</div>
)
}
export default IndexPopup
ユーザーが「Trigger iframe eval」ボタンをクリックすると、サンドボックスページ内で実行されたeval
の結果が表示されます。
詳細については、rfc-263 (opens in a new tab)を参照してください。