JS沙箱

沙箱介绍

我们使用Proxy拦截了用户全局操作的行为,防止对window的访问和修改,避免全局变量污染。micro-app中的每个子应用都运行在沙箱环境,以获取相对纯净的运行空间。

沙箱是默认开启的,正常情况下不建议关闭,以避免出现不可预知的问题。

如何关闭沙箱请查看:disableSandbox

注意事项

1、子应用在沙箱环境中如何获取到真实window

目前有3种方式在子应用中获取外部真实window

  • 1、new Function("return window")() 或 Function("return window")()
  • 2、(0, eval)('window')
  • 3、window.rawWindow

2、子应用抛出错误信息:xxx 未定义

包括:

  • xxx is not defined
  • xxx is not a function
  • Cannot read properties of undefined

原因:

在沙箱环境中,顶层变量不会泄漏为全局变量。

例如在正常情况下,通过 var name 或 function name () {} 定义的顶层变量会泄漏为全局变量,通过window.name或name就可以全局访问。

但是在沙箱环境下这些顶层变量无法泄漏为全局变量,window.name或name的值为undefined,导致出现问题。

解决方式

方式一:手动修改

将 var name 或 function name () {} 修改为 window.name = xx

方式二:通过插件系统修改子应用代码

比如常见的加载webpack打包的dll文件失败的问题,因为dll文件的内容和js地址相对固定,可以直接进行全局查找和修改。

microApp.start({
  plugins: {
    modules: {
      应用名称: [{
        loader(code, url) {
          if (url === 'xxx.js') {
            code = code.replace('var xx_dll=', 'window.xx_dll=')
          }
          return code
        }
      }]
    }
  }
})

3、基座如何对子应用 document 的一些属性进行自定义代理扩展

场景:

微前端模式下,通常由基座负责设置站点标题,不希望受到子应用的干扰。
但是因为 microApp 对 documet 的代理处理过程,并没有处理 document.title,所以子应用中可能通过 document.title = 'xxx' 意外改变了基座的站点标题。

解决方式

通过 customProxyDocumentProps 对 document 的属性进行自定义代理扩展

通过给title设置一个空函数,来忽略 document.title 执行

microApp.start({
  customProxyDocumentProperties: new Map([
    ['title', (value) => {}]
  ]),
})