eval调用导入的TableRowName函数失效,有什么可行的绕过方案?
解决方案
最优方案:移除eval直接调用
完全没必要用eval包裹调用逻辑,直接调用导入的函数即可,不存在作用域和变量识别问题:
TableRowName({ row: row, openDetail: openInfo, resolveCompNum: resolveCompNum, skipParams: skipParams, paramNameMap: paramNameMap })
必须动态执行时的可选方案
如果确实有动态拼接执行逻辑的需求,可按优先级选择以下方案:
- 方案1:将导入函数挂载到全局上下文
把导入的TableRowName挂载到globalThis(全平台通用的全局对象),eval执行时可以直接读取全局上下文的变量:// 导入后先挂载到全局 import TableRowName from './your-module-path.js' globalThis.TableRowName = TableRowName // 执行eval eval("TableRowName({row:row , openDetail:openInfo , resolveCompNum:resolveCompNum , skipParams:skipParams , paramNameMap:paramNameMap })") - 方案2:使用new Function显式传参控制作用域
相比直接eval,new Function的作用域更可控,你可以直接把导入的函数作为参数传入动态生成的函数中,不需要暴露到全局:// 构造动态函数,把需要的变量都作为参数传入 const runDynamicLogic = new Function( 'TableRowName', 'row', 'openInfo', 'resolveCompNum', 'skipParams', 'paramNameMap', `return TableRowName({row:row , openDetail:openInfo , resolveCompNum:resolveCompNum , skipParams:skipParams , paramNameMap:paramNameMap })` ) // 调用时传入导入的函数和对应参数即可 const result = runDynamicLogic(TableRowName, row, openInfo, resolveCompNum, skipParams, paramNameMap) - 方案3:配置构建工具保留变量名
如果是webpack、vite等构建工具压缩时重命名了导入变量导致eval无法识别,可以配置构建规则保留该变量名:// import时添加压缩忽略注释(以Terser压缩器为例) import TableRowName /* #__PURE__ */ /* terser-disable: mangling */ from './your-module-path.js'
注意:eval和动态函数执行都存在安全风险,如果执行的字符串包含不可信的用户输入,会引发代码注入漏洞,非必要场景不建议使用。
内容的提问来源于stack exchange,提问作者marek
相关产品推荐
相关产品推荐

