李金
3 months ago
2 changed files with 112 additions and 0 deletions
@ -0,0 +1,17 @@ |
|||||
|
// 示例使用
|
||||
|
import { DynamicScriptExecutor } from '@/utils/dynamic_script_executor.ts' |
||||
|
|
||||
|
const executor = new DynamicScriptExecutor({ |
||||
|
user: { name: 'Alice', age: 30 }, |
||||
|
sayHello: (name: string) => `Hello, ${name}!` |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
// 代码块中有可能抛出异常的代码
|
||||
|
const result = executor.execute(`
|
||||
|
console.log(user); |
||||
|
throw new Error('测试错误'); // 故意抛出一个错误
|
||||
|
return sayHello(user.name); |
||||
|
`)
|
||||
|
|
||||
|
result.then(console.log).catch(console.error) |
@ -0,0 +1,95 @@ |
|||||
|
type Context = Record<string, any>; |
||||
|
|
||||
|
/** |
||||
|
* 动态执行 JavaScript 脚本的工具类 |
||||
|
*/ |
||||
|
export class DynamicScriptExecutor { |
||||
|
private context: Context |
||||
|
|
||||
|
constructor(context: Context = {}) { |
||||
|
this.context = context |
||||
|
} |
||||
|
|
||||
|
setContext(context: 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 // 语法错误
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async execute(script: string): Promise<any> { |
||||
|
const contextKeys = Object.keys(this.context).join(',') |
||||
|
const contextValues = Object.values(this.context) |
||||
|
|
||||
|
// 先检测代码语法
|
||||
|
const err = this.checkSyntax(script) |
||||
|
if (err !== null) { |
||||
|
console.error('检测到代码语法错误,未执行代码。') |
||||
|
throw err |
||||
|
} |
||||
|
|
||||
|
// 使用 Function 构造函数创建一个新的异步函数,并在其中执行代码
|
||||
|
const func = new Function(contextKeys, `return (async () => { ${script} })();`) |
||||
|
|
||||
|
try { |
||||
|
// 调用函数并传入上下文对象的值
|
||||
|
return await func(...contextValues) |
||||
|
} catch (error) { |
||||
|
this.handleError(error) |
||||
|
throw error |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private handleError(error: any) { |
||||
|
// 在这里处理错误,例如显示错误提示、日志记录、发送错误报告等
|
||||
|
//alert(`执行代码时发生错误: ${error.message}`)
|
||||
|
console.error(`执行代码时发生错误: ${error.message}`) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 创建一个默认的执行器实例
|
||||
|
export const defaultExecutor = new DynamicScriptExecutor({ |
||||
|
|
||||
|
// 系统内置的一些全局对象
|
||||
|
|
||||
|
// 全局对象
|
||||
|
console, |
||||
|
setTimeout, |
||||
|
setInterval, |
||||
|
clearTimeout, |
||||
|
clearInterval, |
||||
|
fetch, |
||||
|
location, |
||||
|
// document,
|
||||
|
FormData, |
||||
|
URLSearchParams, |
||||
|
Headers, |
||||
|
Request, |
||||
|
Response, |
||||
|
Blob, |
||||
|
FileReader, |
||||
|
WebSocket, |
||||
|
EventSource, |
||||
|
localStorage, |
||||
|
sessionStorage, |
||||
|
indexedDB, |
||||
|
crypto, |
||||
|
performance, |
||||
|
navigator, |
||||
|
history, |
||||
|
screen, |
||||
|
alert, |
||||
|
confirm, |
||||
|
prompt, |
||||
|
}) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue