You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go使用otto调用JS函数报错:引入Buffer模块后报Unexpected reserved word

问题原因
  • 报错指向import关键字,核心原因是otto库仅兼容ES5语法规范,不支持ES6及以上的ES Module模块语法,import属于ES6新增的保留字,otto解析时无法识别,直接抛出保留字异常。
  • 额外注意:即使删掉import语句,代码也会报错,因为Buffer是Node.js内置API,otto的JS运行时没有内置任何Node.js核心模块,无法直接识别Buffer对象。
解决方案

可以根据你的业务需求任选以下一种方案处理:

方案1:移除模块导入,改用ES5兼容实现

如果你的Buffer使用逻辑比较简单,可以直接替换为otto支持的原生ES5 API,不需要引入额外依赖,修改后的secret.js示例如下:

// 删掉import语句,直接用ES5兼容API实现逻辑
var Q = function(e) {
    // 示例:如果要做base64编码,直接用otto原生支持的btoa方法
    return btoa("asdfl" + e)
};

如果需要用到二进制处理能力,也可以直接用ES5原生支持的Uint8Array等类型实现。

方案2:注入Buffer实现到otto运行时

可以在Go侧直接给otto虚拟机注入Buffer构造函数,在Go层实现对应的编码能力,无需修改JS代码的核心逻辑:
修改后的main.go示例:

import "encoding/base64"

func main() {
    jsFile := "./secret.js"
    bytes, err := ioutil.ReadFile(jsFile)
    if err != nil {
        panic(err)
    }

    vm := otto.New()
    // 提前注入Buffer实现到JS运行时
    vm.Set("Buffer", func(call otto.FunctionCall) otto.Value {
        input, _ := call.Argument(0).ToString()
        // 这里在Go层实现你需要的Buffer逻辑,示例为转base64
        res := base64.StdEncoding.EncodeToString([]byte(input))
        val, _ := vm.ToValue(res)
        return val
    })
    _, err = vm.Run(string(bytes))
    if err != nil {
        panic(err)
    }
    enc, err := vm.Call("Q", nil, "123456")
    if err != nil {
        panic(err)
    }
    fmt.Println(enc.String())
}

对应的secret.js直接删掉第一行的import语句即可。

方案3:打包JS为单文件ES5代码

如果你的JS依赖比较多,需要用Node.js模块,可以用browserify、webpack等打包工具,把所有依赖打包为单文件的ES5兼容代码,自动剔除import/export等ES6语法,打包后的文件可以直接在otto中运行。

内容的提问来源于stack exchange,提问作者xiun xiao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 14:54:05