import React from 'react' type Context = Record; /** * 动态执行 JavaScript 脚本的工具类 */ export class DynamicScriptExecutor { private context: Context private startDelimiter: string private endDelimiter: string constructor(context: Context = {}, startDelimiter: string = '{{', endDelimiter: string = '}}') { this.context = context this.startDelimiter = startDelimiter this.endDelimiter = endDelimiter } setDelimiters(startDelimiter: string, endDelimiter: string) { this.startDelimiter = startDelimiter this.endDelimiter = endDelimiter } setContext(context: Context) { this.context = { ...this.context, ...context } } // 检测JS代码的语法是否正确 checkSyntax(script: string) { const contextKeys = Object.keys(this.context).join(',') try { // 尝试创建一个新的函数,如果代码有语法错误,这里会抛出异常 new Function(contextKeys, `return (async () => { ${script} })();`) return null // 语法正确 } catch (error) { console.error('代码语法错误:', error) return error // 语法错误 } } // 自动识别并提取动态JS执行块 extractDynamicJSBlocks(input: string): string[] { const regex = new RegExp( `${this.escapeRegExp(this.startDelimiter)}(.*?)${this.escapeRegExp(this.endDelimiter)}`, 'gs' ) const matches: string[] = [] let match while ((match = regex.exec(input)) !== null) { matches.push(match[1].trim()) } return matches } // 执行所有提取的动态JS块 async execute(input: string): Promise { const dynamicBlocks = this.extractDynamicJSBlocks(input) const results: any[] = [] for (const script of dynamicBlocks) { const contextKeys = Object.keys(this.context).join(',') const contextValues = Object.values(this.context) const error = this.checkSyntax(script) if (error !== null) { throw error // 抛出异常以便在调用方捕获 } const func = new Function(contextKeys, `return (async () => { ${script} })();`) try { results.push(await func(...contextValues)) } catch (error) { this.handleError(error) throw error } } return results } private handleError(error: any) { console.log(`执行代码时发生错误: ${error.message}`) } // 转义正则表达式中的特殊字符 private escapeRegExp(string: string): string { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') } } // 创建一个默认的执行器实例 export const defaultExecutor = new DynamicScriptExecutor({ // 系统内置的一些全局对象 // 全局对象 console, setTimeout, setInterval, clearTimeout, clearInterval, fetch, location, React, // document, FormData, URLSearchParams, Headers, Request, Response, Blob, FileReader, WebSocket, EventSource, localStorage, sessionStorage, indexedDB, crypto, performance, navigator, history, screen, alert, confirm, prompt, })