沙盒到底是什么?
有两种类型的自定义扩展:
- 沙盒化扩展
- 非沙盒化扩展
这种差异对你的扩展有重大影响。到目前为止,我们主要关注创建沙盒化扩展,但这意味着什么?
沙盒
沙盒实际上是一个 <iframe>。沙盒化扩展在一个沙盒化的跨域 iframe 中运行,无法直接访问带有编辑器和 VM 的主页面;它被困在自己隔离的世界中。
因此,沙盒化扩展:
- 无法访问 Scratch 内部
- 无法访问任何未作为参数传入的项目部分,包括变量
- 完全无法直接与角色交互
然而,它们可以:
- 访问大多数公共 API,只要 CORS 允许
- 访问一些 JavaScript Web API,例如 Gamepad API
值得注意的是,在其他 Scratch 修改版中,扩展沙盒可能是 Worker 而不是 <iframe>。我们使用 <iframe> 是因为它更安全(跨域 vs 同源)并允许访问更多 Web API。
也许最大的限制是,每次运行积木时,脚本将暂停至少 1 帧,无论脚本有多简单。无论是否启用"不刷新屏幕运行"或加速模式,它都会等待。
这是一个非常重要的限制,它使自定义扩展几乎无用,这就是为什么我们引入了对...的支持。
非沙盒化扩展
顾名思义,非沙盒化扩展不在 iframe 中运行。它们作为 <script> 标签在与 Scratch 本身相同的上下文中运行。
这意味着非沙盒化扩展:
- 可以访问 Scratch 内部
- 可以访问未作为参数传入的项目部分,例如变量
- 可以直接与任何角色交互
也许最重要的是,从非沙盒化扩展运行积木实际上是即时的——没有强制的 1 帧延迟。
练习
- 创建一个沙盒化扩展(与我们到目前为止构建的相同),其中包含一个什么都不做的 COMMAND 积木。创建一个新的空项目,并创建一个重复(10)循环,运行此积木 4 次。观察到,即使积木什么都不做,循环也需要超过一秒才能完成。
- 在重复执行中,将扩展中的积木替换为"设置我的变量为 0"积木。观察到循环立即完成。这是非沙盒化扩展的积木的行为方式。
- 在自定义扩展中,使用 console.log 输出
window.origin的值。将此与在 turbowarp.org 上的浏览器开发者控制台中运行window.origin进行比较。
下一步
非沙盒化扩展显然更好,所以让我们写一个。