JS 沙箱实现方案
沙箱概述
在计算机安全中,Sandbox 是一种用于隔离正在运行程序的安全集资,通常用于执行未经测试或者不受信任的程序或者代码,它回为待执行的程序创建一个独立的执行环境,内部程序的执行不会影响外部程序的执行。
js 沙箱的使用场景
jsonp: 在解析服务器返回的jsonp数据的时候,如果不信任jsonp的数据,可以通过创建沙箱的方式来获取数据;执行第三方js(不受信任的js)的时候在线代码编辑器: 在线编辑器中一般讲代码放在沙箱中执行,避免对页面本身造成影响vue 服务端渲染: vue 的服务端渲染, 通过创建沙箱执行前端的bundle文件;在调用createBundleRender方法的时候,允许配置runlnNewContext为true或false的形式,判断是否传入一个新创建的sandbox对象以供vm使用vue 模板中的表达式: vue 模板中表达式的计算被放在沙盒中,只能访问全局变量的一个白名单,如Math和Date.你不能在模板表达式中试图访问用户定义的全局变量
js 沙箱的实现方式
<一>、 基于iframe的沙箱环境实现
通过iframe来创建沙箱环境是一种常用的方法,iframe本身就是一个封闭的沙箱环境,假如即将执行的代码不是我们自己的代码,是不可信任的数据,那么可以通过iframe来执行
1.1使用iframe及自定义消息传递机制跨窗口通信
同源策略会限制窗口之间进行通信:
* 如果我们对一个同源的窗口进行引用,是具有访问权限的
* 如果我们想对不同源的窗口进行访问,我们就没有权限访问这个窗口下的内容(变量、文档、上下文),但是location是例外的,通过location我们可以实现窗口间的跳转,但是我们无法获取到location的信息,无法看到用户当前所处的位置。
1.2 iframe简介
iframe 标签可以单独创建一个新的窗口,这个新的窗口有自己的document和window
1.2.1 基本属性
frameborder: 是否显示边框height: 框架作为一个普通元素的高度- *
width: 宽度 *name: 框架名称,window.frames[name] scrolling: 框架是否滚动 *scr: 框架地址或者页面地址srcdoc: 用于替换原来在HTML Body中的内容sandbox: 对iframe进行一列限制
*同域情况下我们可以自由操作iframe和父框架的内容DOM,但是跨域条件下就只能进行页面跳转*
1.2.2 获取iframe 中的内容
- iframe.contentWindow: 获取iframe的window对象
- iframe.contentDocument: 获取iframe的document对象
1.2.3 在iframe中获取父级内容(同域)
- window.parent: 获取上一级的window对象,如果还是iframe则是改iframe的window对象
- window.top: 获取顶级容器的window对象
- window.self: 返回自身的window引用
1.2.4 sandbox
- 启用sandbox之后会对iframe页面进行一系列的限制:
- script 脚本不能执行
- 不能发送ajax请求
- 不能使用本地存储,localstroage,cookie
- 不能创建信的弹窗和window
- 不能发送表单
- 不能加载额外插件,flash等
- sandbox 常用配置:
- allow-forms: 允许提交表单
- allow-script: 允许运行脚本
- allow-same-origin: 允许同域请求,ajax,stroge
- allow-top-navigation: 允许iframe能够主导window.top进行页面跳转
- allow-popups: 允许iframe中弹出新窗口(window.open, target=“_blank”)
- allow-pointer-lock: 在iframe中可以锁定鼠标,主要和鼠标锁定有关
使用iframe实现微前端有哪些优点?
- 实现简单:子应用之间自带沙箱,天然隔离,互不影响
- 技术限制:可以各自使用完全不同的前端框架
- 消息传递: 只要每个iframe来自同一个源,就可以使用window.postMessageAPI进行消息传递
使用iframe实现微前端有哪些缺点
- Buddle的大小各异,构建时不能提取公共依赖关系
- 不支持SEO
- URL不同步: iframe页面url中的状态信息不能同步到父窗口,无法使用浏览器的前进和后退功能
- DOM结构不共享: iframe的页面布局只针对iframe窗口
- 全局上下问完全隔离,内存变量不共享
- 启动慢: 每次微应用进入都是一次浏览器上下问重建、资源重新加载的过程
<二>、基于Proxy的沙箱实现
基于沙箱实现沙箱的主要原理是,通过Proxy劫持沙箱全局window,记录对全局对象属性的更改,来修改window对象的属性和方法,在卸载和加载应用时关闭/激活沙箱,达到模拟沙箱的目的
代理沙箱基本实现
Proxy Sandbox
<三>、diff方式实现沙箱
在不支持proxy的浏览器中,可以通过diff的方式实现沙箱
- 在运行子应用时保存一个window的快照对象,将当前的window对象全部复制到这个快照对象中
- 子应用卸载时将window对象和快照对象对象进行diff,将不同的属性保存下来,再次挂载的时候再添加上这些属性
diff 实现沙箱
Diff Sandbox
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
