字符串函数安全解析成执行函数

发布于:2025-07-30 ⋅ 阅读:(26) ⋅ 点赞:(0)

字符串函数安全解析成执行函数

可以通过创建沙箱环境(注入组件方法和工具函数)使用组件内部函数

// 组件安全函数解析器
function safeParseFunction(fnStr: string, context = {}) {
  if (typeof fnStr !== 'string') return fnStr;

  // 增强预处理:处理Vue模板中的转义字符
  const processedStr = fnStr
    .trim()
    .replace(/\\n/g, '\n') // 转换转义换行符
    .replace(/\\t/g, ' ') // 转换制表符为空格
    .replace(/\\"/g, '"') // 处理转义引号
    .replace(/\r/g, '') // 移除回车符
    .replace(/\s+/g, ' '); // 压缩连续空格

  try {
    // 创建沙箱环境(注入组件方法和工具函数)
    const sandbox = {
      // 注入组件API
      ...context,
      // 注入工具函数
    
      // 注入基础API
      console,
      setTimeout,
      clearTimeout,
      setInterval,
      clearInterval
      // 其他需要注入的依赖...
    };

    // 重构函数构建逻辑(避免with语句作用域问题)
    const createExecutor = () => {
      const sandboxKeys = Object.keys(sandbox);
      // const sandboxValues = sandboxKeys.map((key) => sandbox[key]);

      // 动态生成函数参数列表
      const params = sandboxKeys.join(', ');

      // 构建函数体(三种格式统一处理)
      let fnBody = processedStr;
      if (fnBody.includes('=>')) {
        if (!fnBody.startsWith('(')) {
          fnBody = `(${fnBody})`; // 补全箭头函数括号
        }
      } else if (!fnBody.startsWith('function')) {
        fnBody = `function() { ${fnBody} }`; // 包裹普通函数体
      }

      // 生成可执行函数
      return new Function(params, `return (${fnBody}).apply(this, arguments)`);
    };

    // 执行并绑定上下文
    const executor = createExecutor();
    return (...args) =>
      executor.apply(sandbox, Object.values(sandbox).concat(args));
  } catch (error: any) {
    console.error('[函数解析失败]', {
      input: fnStr,
      error: error.message
    });
    return () => {};
  }
}

// 测试用例(在组件中验证)   { emit, props }
const testFunction = safeParseFunction(
  "()=>{\n console.log(11);\n setTimeout(()=>{console.log(12)},100);\n}"

);
testFunction(); // 应正常执行

网站公告

今日签到

点亮在社区的每一天
去签到