Acorn解析传入脚本(前端js脚本格式校验)

场景需求:

       现在前端有一个js脚本输入框,要对用户写的脚本做函数验证,要保证用户写的函数正确,必须保证有rawDataToProtocol和protocolToRawData这两个函数才正确,如果只有一个或者其它函数名均是不正确的,且函数格式不正确也会有提示;

参考:angular-expressions、expr-eval、acorn

项目技术:Vue3+Ts

最终决定使用:Acorn,原因下载量大,最合适,一直处于维护状态长达十几年,且使用配置规范合理,适合Js解析

代码实现如下:

// 异步函数,接收一个脚本作为参数
async function updateFunctionValidation(script) {
  // 返回一个 Promise 对象,用于处理异步逻辑
  return new Promise((resolve, reject) => {
    try {
      // 使用 acorn 解析传入的脚本,指定 ECMAScript 版本为 2020,模块化类型为 "module"
      const ast = acorn.parse(script, { ecmaVersion: 2020, sourceType: "module" });

      // 初始化两个标志,用于检测是否找到了特定的函数
      let foundRawDataToProtocol = false;
      let foundProtocolToRawData = false;

      // 定义 AST 遍历函数
      // eslint-disable-next-line no-inner-declarations
      function traverse(node) {
        // 检查节点类型是否为函数声明
        if (node.type === "FunctionDeclaration") {
          // 判断函数名是否匹配
          if (node.id && node.id.name === "rawDataToProtocol") {
            foundRawDataToProtocol = true;
          } else if (node.id && node.id.name === "protocolToRawData") {
            foundProtocolToRawData = true;
          }
        }
        // 递归遍历子节点
        for (const key in node) {
          if (node[key] && typeof node[key] === "object") {
            traverse(node[key]);
          }
        }
      }

      // 调用遍历函数
      traverse(ast);

      // 验证是否只包含指定的函数名
      const isScriptValid = foundRawDataToProtocol && foundProtocolToRawData;

      // 如果脚本不合法,抛出错误
      if (!isScriptValid) {
        throw new Error("Invalid script. It should only contain 'rawDataToProtocol' and 'protocolToRawData' functions.");
      }

      // 如果一切正常,解析成功,调用 resolve 完成 Promise
      resolve();
    } catch (error) {
      // 捕获异常,打印错误信息
      console.error("An error occurred while parsing script:", error.message);
      // 在出现错误时,将相关验证标志置为 false,并调用 reject
      functionValidation.value.rawDataToProtocol = false;
      functionValidation.value.protocolToRawData = false;
      reject(error);
    }
  });
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值