js 沙箱

61 阅读1分钟
const sandboxProxy = (window, document) => {
  const cloneDocument = document.cloneNode(true);
  const cloneWindow = { ...window };
  const proxyWindow = new Proxy(cloneWindow, {
    has: function () {
      // 拦截属性检查,总是返回 false,迫使 with 块中的查找进入沙盒对象
      return true;
    },
    get: function (target, key) {
      if (key === Symbol.unscopables) return undefined;
      // 返回沙盒对象中的属性,如果不存在则返回 undefined
      return target[key];
    },
    set: function (target, key, value) {
      // 设置属性值,影响只限于沙盒内部
      target[key] = value;
      return true;
    }
  });
  const proxyDocument = new Proxy(cloneDocument, {
    has: function () {
      // 拦截属性检查,总是返回 false,迫使 with 块中的查找进入沙盒对象
      return true;
    },
    get: function (target, key) {
      if (key === Symbol.unscopables) return undefined;
      // 返回沙盒对象中的属性,如果不存在则返回 undefined
      return target[key];
    },
    set: function (target, key, value) {
      // 设置属性值,影响只限于沙盒内部
      target[key] = value;
      return true;
    }
  });
  return {window:proxyWindow, document:proxyDocument};
};

function executeSandboxCode (){
  const globalObject = sandboxProxy(window,document);
  const sandboxfunction =   new Function(`globalObject`,`with(globalObject){
    return function(){
      // 这就是沙箱代码
      console.log('看看这个window',window);
      console.log('看看这个document',document);
      console.log('看看这个this',this);
    }
  }`);
  sandboxfunction(globalObject).call(globalObject.window);
};

executeSandboxCode()