沙盒页面
沙盒页面是具有不同 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 属性评估调用者发送的代码。沙盒页面现在在扩展包中的 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 输出: " + event.data)
})
}, [])
return (
<div
style={{
display: "flex",
flexDirection: "column",
padding: 16
}}>
<button
onClick={() => {
iframeRef.current.contentWindow.postMessage("10 + 20", "*")
}}>
触发 iframe eval
</button>
<iframe src="sandbox.html" ref={iframeRef} style={{ display: "none" }} />
</div>
)
}
export default IndexPopup当用户点击 trigger iframe eval 时,他们将看到在沙盒页面中完成的 eval 结果。
有关更多详细信息,请参见 rfc-263 。
最后更新于