跳到主要内容

js

js 库内嵌一个 JavaScript 运行时(goja),可在 yak 脚本中执行 JS 代码、调用 JS 函数、解析 JS AST,并内置 CryptoJS、JSEncrypt、jsrsasign 等常用前端加密库,常用于还原前端加密逻辑、对抗 JS 混淆与参数加签。

典型使用场景:

  • 执行与调用:js.Run 执行 JS 代码,js.CallFunctionFromCode 直接调用源码中的函数,js.New 创建可复用运行时,js.ToValue 在 yak/JS 值间转换。
  • 解析:js.Parse / js.ASTWalk 解析与遍历 JS AST(用于分析前端逻辑)。
  • 内置加密库:js.libCryptoJSV3 / js.libCryptoJSV4 / js.libJSRSASign / js.libJsEncrypt 注入常用前端加密库,js.withVariable(s) 注入变量。

与相邻库的关系:js 常配合 crawler/crawlerx(前端逻辑分析)、codec(加解密)、fuzz(构造加密参数)使用,用于"用前端的算法生成请求参数"的场景。

共 15 个函数、6 个实例

实例​

实例名类型说明
FalseValuegoja.valueBoolfalse
NaNValuegoja.valueFloatNaN
NullValuegithub.com/yaklang/goja.valueNullnull
PoweredBystring"github.com/yaklang/goja"
TrueValuegoja.valueBooltrue
UndefinedValuegithub.com/yaklang/goja.valueUndefinedundefined

函数索引​

函数参数返回值说明
js.ASTWalkcode string*ASTWalkerResult, error对传入的 JS 代码进行 AST 遍历,收集字面量、标识符与语法错误(导出名为 js.ASTWalk)
js.GetFunctionvm *goja.Runtime, funcName stringjsFunction, bool从 JS 引擎中取出某个全局函数并转换为可调用函数
js.GetObjectFunctionvm *goja.Runtime, thisName string, funcName stringjsFunction, bool从 JS 引擎中取出某个对象的方法并转换为可调用函数
js.GetSTTypest anystringGetStatementType 返回 JS AST 节点的类型名(去掉 *ast. 前缀,导出名为 js.GetSTType)
js.Parsecode string*ast.Program, error对传入的 JS 代码进行解析并返回 AST 语法树
js.ToValuei anygoja.Value将一个 Go 值转换为 JS 运行时中的值(JS Value),便于作为变量注入 JS 环境或与执行结果交互(导出名为 js.ToValue)
js.libCryptoJSV3-jsRunOpts是一个 JS 运行选项参数,用于在运行 JS 代码时嵌入 CryptoJS 3.3.0 库
js.libCryptoJSV4-jsRunOpts是一个 JS 运行选项参数,用于在运行 JS 代码时嵌入 CryptoJS 4.2.0 库
js.libJSRSASign-jsRunOpts是一个 JS 运行选项参数,用于在运行 JS 代码时嵌入 jsrsasign 10.8.6 库
js.libJsEncrypt-jsRunOpts是一个 JS 运行选项参数,用于在运行 JS 代码时嵌入 JSEncrypt 3.3.2 库
js.withVariablename string, value anyjsRunOpts为 JS 运行设置单个全局变量(导出名为 js.withVariable)
js.withVariablesvars map[string]anyjsRunOpts为 JS 运行批量设置多个全局变量(导出名为 js.withVariables)

可变参数函数索引​

函数参数返回值说明
js.CallFunctionFromCodesrc any, funcName string, params ...anygoja.Value, error从传入代码中调用指定的 JS 函数并返回结果
js.Newopts ...jsRunOpts*goja.Runtime创建一个新的 JS 引擎(goja Runtime)并返回
js.Runsrc any, opts ...jsRunOpts*goja.Runtime, goja.Value, error创建新的 JS 引擎并运行传入代码,返回引擎、运行结果值和错误

函数详情​

ASTWalk​

ASTWalk(code string) (*ASTWalkerResult, error)

对传入的 JS 代码进行 AST 遍历,收集字面量、标识符与语法错误(导出名为 js.ASTWalk)

参数

参数名类型说明
codestringJS 源代码字符串

返回值

序号类型说明
r1*ASTWalkerResult遍历结果(含字符串字面量、标识符、语法错误等)
r2error错误信息

示例

res = js.ASTWalk(`var name = "yak"; foo("bar");`)~
dump(res)

GetFunction​

GetFunction(vm *goja.Runtime, funcName string) (jsFunction, bool)

从 JS 引擎中取出某个全局函数并转换为可调用函数

参数

参数名类型说明
vm*goja.RuntimeJS 引擎
funcNamestring函数名

返回值

序号类型说明
r1jsFunction可调用的 JS 函数
r2bool是否成功获取

示例

vm, _ = js.Run(`function sum(a, b) {return a+b;}`)~
sum, ok = js.GetFunction(vm, "sum")
assert ok, "should get function sum"
assert sum(2, 3)~.ToInteger() == 5, "sum(2,3) should be 5"

GetObjectFunction​

GetObjectFunction(vm *goja.Runtime, thisName string, funcName string) (jsFunction, bool)

从 JS 引擎中取出某个对象的方法并转换为可调用函数

参数

参数名类型说明
vm*goja.RuntimeJS 引擎
thisNamestring对象名
funcNamestring方法名

返回值

序号类型说明
r1jsFunction可调用的 JS 函数
r2bool是否成功获取

示例

vm, _ = js.Run(`a = { d: 3, add(a) {return this.d+a} }`)~
add, ok = js.GetObjectFunction(vm, "a", "add")
assert ok, "should get object method add"
assert add(1)~.ToInteger() == 4, "a.add(1) should be 4"

GetSTType​

GetSTType(st any) string

GetStatementType 返回 JS AST 节点的类型名(去掉 *ast. 前缀,导出名为 js.GetSTType)

参数

参数名类型说明
stanyJS AST 节点(如 js.Parse 的返回值或其子节点)

返回值

序号类型说明
r1string节点类型名字符串

示例

tree = js.Parse("function add(a, b) { return a + b; }")~
println(js.GetSTType(tree)) // OUT: Program
assert js.GetSTType(tree) == "Program", "parsed root node should be Program"

Parse​

Parse(code string) (*ast.Program, error)

对传入的 JS 代码进行解析并返回 AST 语法树

参数

参数名类型说明
codestringJS 源代码字符串

返回值

序号类型说明
r1*ast.Program解析得到的 AST 程序节点
r2error错误信息

示例

tree = js.Parse(`function add(a, b) { return a + b; }`)~
assert tree != nil, "parse should return a non-nil AST"
println(js.GetSTType(tree)) // OUT: Program

ToValue​

ToValue(i any) goja.Value

将一个 Go 值转换为 JS 运行时中的值(JS Value),便于作为变量注入 JS 环境或与执行结果交互(导出名为 js.ToValue)

参数

参数名类型说明
iany任意 Go 值(数字、字符串、布尔、map、slice 等)

返回值

序号类型说明
r1goja.Value转换后的 JS 值

示例

v = js.ToValue("hello")
assert v != nil, "ToValue should convert a go value to a js value"

libCryptoJSV3​

libCryptoJSV3() jsRunOpts

是一个 JS 运行选项参数,用于在运行 JS 代码时嵌入 CryptoJS 3.3.0 库

返回值

序号类型说明
r1jsRunOptsJS 运行选项

示例

_, value = js.Run(`CryptoJS.HmacSHA256("Message", "secret").toString();`, js.libCryptoJSV3())~
assert value.String() == "aa747c502a898200f9e4fa21bac68136f886a0e27aec70ba06daf2e2a5cb5597", "HmacSHA256 should be deterministic"

libCryptoJSV4​

libCryptoJSV4() jsRunOpts

是一个 JS 运行选项参数,用于在运行 JS 代码时嵌入 CryptoJS 4.2.0 库

返回值

序号类型说明
r1jsRunOptsJS 运行选项

示例

_, value = js.Run(`CryptoJS.HmacSHA256("Message", "secret").toString();`, js.libCryptoJSV4())~
assert value.String() == "aa747c502a898200f9e4fa21bac68136f886a0e27aec70ba06daf2e2a5cb5597", "HmacSHA256 should be deterministic"

libJSRSASign​

libJSRSASign() jsRunOpts

是一个 JS 运行选项参数,用于在运行 JS 代码时嵌入 jsrsasign 10.8.6 库

返回值

序号类型说明
r1jsRunOptsJS 运行选项

示例

// 无法本地验证: 需要在 JS 中先定义有效的 PEM 公钥变量 pemPublicKey
// 加载 jsrsasign 库后即可在 JS 里用 KEYUTIL 做 RSA 加解密
_, value = js.Run(`KEYUTIL.getKey(pemPublicKey).encrypt("yaklang")`, js.libJSRSASign())~
println(value.String())

libJsEncrypt​

libJsEncrypt() jsRunOpts

是一个 JS 运行选项参数,用于在运行 JS 代码时嵌入 JSEncrypt 3.3.2 库

返回值

序号类型说明
r1jsRunOptsJS 运行选项

示例

_, value = js.Run("var encrypt = new JSEncrypt(); 'ok';", js.libJsEncrypt())~
assert value.String() == "ok", "JSEncrypt lib should be embedded successfully"

withVariable​

withVariable(name string, value any) jsRunOpts

为 JS 运行设置单个全局变量(导出名为 js.withVariable)

参数

参数名类型说明
namestring变量名
valueany变量值

返回值

序号类型说明
r1jsRunOptsJS 运行选项

示例

_, value = js.Run("a + b", js.withVariable("a", 1), js.withVariable("b", 2))~
println(value.ToInteger()) // OUT: 3
assert value.ToInteger() == 3, "a + b with injected variables should be 3"

withVariables​

withVariables(vars map[string]any) jsRunOpts

为 JS 运行批量设置多个全局变量(导出名为 js.withVariables)

参数

参数名类型说明
varsmap[string]any变量名到变量值的映射

返回值

序号类型说明
r1jsRunOptsJS 运行选项

示例

_, value = js.Run("a + b", js.withVariables({"a": 10, "b": 5}))~
println(value.ToInteger()) // OUT: 15
assert value.ToInteger() == 15, "a + b with injected variables should be 15"

可变参数函数详情​

CallFunctionFromCode​

CallFunctionFromCode(src any, funcName string, params ...any) (goja.Value, error)

从传入代码中调用指定的 JS 函数并返回结果

必填参数

参数名类型说明
srcany包含 JS 代码的字符串
funcNamestring要调用的 JS 函数名

可选参数

参数名类型说明
params...any零个或多个函数参数

返回值

序号类型说明
r1goja.Value函数调用的返回值
r2error错误信息

示例

value = js.CallFunctionFromCode(`function add(a, b) { return a + b; }`, "add", 1, 2)~
println(value.ToInteger()) // OUT: 3
assert value.ToInteger() == 3, "add(1,2) should be 3"

New​

New(opts ...jsRunOpts) *goja.Runtime

创建一个新的 JS 引擎(goja Runtime)并返回

可选参数

参数名类型说明
opts...jsRunOpts零个或多个运行选项,如嵌入第三方库或预置变量

返回值

序号类型说明
r1*goja.RuntimeJS 引擎对象,可调用 RunString 执行 JS 代码

示例

engine = js.New()
val = engine.RunString("1+1")~.ToInteger()
println(val) // OUT: 2
assert val == 2, "js engine should evaluate 1+1 to 2"

Run​

Run(src any, opts ...jsRunOpts) (*goja.Runtime, goja.Value, error)

创建新的 JS 引擎并运行传入代码,返回引擎、运行结果值和错误

会尝试自动导入代码中用到的库(CryptoJS 默认导入 V4 版本)

必填参数

参数名类型说明
srcany要运行的 JS 代码字符串

可选参数

参数名类型说明
opts...jsRunOpts零个或多个运行选项,如嵌入第三方库或预置变量

返回值

序号类型说明
r1*goja.RuntimeJS 引擎对象
r2goja.Value运行结果值
r3error错误信息

示例

_, value = js.Run("1+1")~
println(value.ToInteger()) // OUT: 2
assert value.ToInteger() == 2, "js.Run should evaluate 1+1 to 2"