Apifox 教程:如何实现跨语言调用(Java、PHP、Python、Go 等)

在一些特定场景下,比如需要在 Apifox 中对文件进行读写、加密、转换格式或者进行其它业务的操作时,仅使用 Apifox 内置的 JS 类库可能无法满足业务需求,这时,就可以借助「外部程序」作为解决方案。

外部程序是保存在「外部程序目录」下的代码文件,可以是 Java 程序归档文件 jar 包,也可以是其他程序的代码源文件,例如 .jar、.py、.php、.js 等后缀的文件。文件需要放到「外部程序目录」下,这个目录可以在页面右上角的「设置 -> 外部程序」中打开。

使用「外部程序」时需要注意两点:

  1. Apifox 版本必须是 2.3.25 或以上才支持调用外部程序。
  2. 外部程序是在「沙盒环境」以外运行的,这意味着它有权限访问你电脑上的其他程序、文件和数据,所以要确保外部程序是安全的。

调用「外部程序」的语法

在 Apifox 中调用外部程序可以使用 pm.executeAsync() 方法,其语法如下,可将其写在接口的「前置/后置操作」中:

复制代码
await pm.executeAsync(filePath, args, options)

其内各项参数表示如下,更具体的可参考帮助文档里的解释。

  • filePath (string) : 外部程序路径。
  • args (string\[\]) : 传递给外部程序的参数,数组中每个字符串代表一个参数。其中,非 string 类型会隐式转换为 string 类型。
  • options (Object) : 其他选项设置,包括:
    • command (string) : 外部程序的执行命令。非必填,如果不填会自动推断。
    • cwd (string) : 子进程工作目录。非必填,默认为「外部程序目录」。
    • env (Record) : 子进程环境变量。非必填,默认为 {}。
    • windowsEncoding (string) : Windows 系统用使用的编码格式。非必填,默认为 "cp936"。
    • className (string) : 调用 jar 包中的类名,非必填,详见 jar 包中的方法。
    • method (string) : 调用 jar 包中的方法名,当 className 有值时为必填项。
    • paramTypes (string\[\]) : 指定 jar 包中方法参数的类型,默认根据参数自动推断。

在调用外部程序时,Apifox 会启动一个子进程,在里面以命令行的方式运行你指定的外部程序,然后,会把子进程的标准输出 (stdout) 作为外部程序的返回值。

这么说可能有点绕,简单讲就是 Apifox 会根据 pm.executeAsync() 方法里的参数生成一个命令,然后用命令去执行这个外部程序,并捕获输出的结果。例如:脚本 pm.executeAsync('add.py', '2', '3') 的实际执行命令为 python add.py 2 3。

举个更具体的例子。

假设你有一个 Python 脚本,用于计算两个数字的和。现在,你想在 Apifox 中调用这个外部的 Python 脚本,就可以使用 pm.executeAsync() 方法,具体如下。

准备外部程序

首先,你需要创建一个 Python 文件并将其放到「外部程序目录」下,例如 add.py,在脚本中,你一般需要处理传入的参数,并生成相应的输出。

复制代码
# add.pyimport sys
# 从命令行参数中获取两个数字num1 = int(sys.argv[1])num2 = int(sys.argv[2])
# 计算两个数字的和result = num1 + num2
# 将结果打印到标准输出(stdout)print(result)

1 处理传入的参数

外部程序在 Apifox 中是以命令行的方式执行的,所以外部程序只能从命令行中获取到传入的参数。

上述脚本中的 sys.argv 是 Python 用于获取命令行参数的方法。例如使用 pm.executeAsync('add.py', 2, 3) 调用外部脚本,其实际执行命令为 python add.py 2 3,则在外部脚本 add.py 中,获取参数的方式为:

复制代码
# 从命令行参数中获取两个数字num1 = int(sys.argv[1]) // 2num2 = int(sys.argv[2]) // 3

每种编程语言获取命令行参数的方式与该语言的语法相关联,不同的编程语言会有不同的机制来处理命令行参数,举例来说:

  • 在 Python 中,你可以使用 sys.argv 列表来访问命令行参数。
  • 在 JavaScript 中,如果你在 Node.js 环境下运行脚本,你可以使用 process.argv 来获取命令行参数。
  • 在 Java 中,命令行参数可以通过 args\[\] 参数传递给 main() 方法。

2 生成相应的输出

Apifox 不会捕获函数的返回值 (return) ,而是依赖于程序的标准输出 (stdout) 。

上述脚本里的 print() 作为 Python 的标准输出 (stdout) ,将计算结果输出到控制台或终端,Apifox 会捕获到这个输出结果,所以你将结果打印出来就可以将其返回。其它编程语言如 JavaScript 的 console.log()、Java 的 System.out.println() 也作为标准输出,具体取决于每种编程语言的语法。

外部程序建议先进行单独测试,确保其可以独立运行并产生预期结果,然后再在 Apifox 中调用,例如使用命令行 python add.py 2 3 运行这个文件,就会打印出结果。

其它类型的外部程序,比如要将一个图片文件转成 Base64、读取或保存图片文件、将 Word、PDF 等文件进行加密或者其它一系列你需要的操作,都建议先手动运行程序并检查输出。

在前置/后置操作中调用

外部程序准备好以后,你可以在 Apifox 的「前置/后置操作」中创建一个自定义脚本,然后使用 pm.executeAsync() 方法来调用「步骤一」中的外部程序。以下是一个示例:

复制代码
// 使用 pm.executeAsync 调用 Python 脚本async function callPythonScript() {    // 外部程序的路径为 add.py    const scriptPath = 'add.py';    // 传递给 Python 脚本的参数,例如两个数字 2 和 3    const args = ['2', '3'];
    try {        // 调用 Python 脚本,并等待结果        const result = await pm.executeAsync(scriptPath, args);        console.log('Result:', result);    } catch (error) {        console.error('Error:', error);    }}
// 调用函数开始执行callPythonScript();

这个示例可以简化成下面这样的:

复制代码
// 外部程序路径,传递参数const result = await pm.executeAsync('add.py', ['2', '3'])console.log('Result:', result);

传递的参数除了常量/固定值以外,你还可以通过变量的方式进行传递,例如:

复制代码
// 读取环境变量的值const scriptPath = pm.environment.get('scriptPath')const arg1 = pm.environment.get('arg1')const arg2 = pm.environment.get('arg2')
const result = await pm.executeAsync(scriptPath, [arg1, arg2])console.log('Result:', result);

Apifox 会根据你提供的参数拼接出一个命令字符串,比如这个例子中 pm.executeAsync('add.py', '2', '3') 方法拼接成的命令就是:

复制代码
python add.py 2 3

这跟你在本地运行这个 add.py 文件时使用的命令相一致。

当你在 Apifox 中发送请求时,会执行这个 JavaScript 脚本,并通过生成的命令调用外部程序 add.py,以获取外部程序的输出结果,如下图所示:

在 Apifox 中获取到的返回结果为 String 类型,你可根据实际需要进行类型转换。结果获取到之后,可将结果存储到环境变量中,以供取用,语法参考如下:

复制代码
pm.environment.set('变量名', '变量值');

常见问题

1 macOS 提示找不到 Python 命令

在 macOS 系统上,默认安装了 Python 3 而不是 Python 2,要执行 Python 脚本,可使用 pm.executeAsync() 方法并设置参数 command 值为 "python3" 来确保使用正确的 Python 版本,例如:

复制代码
await pm.executeAsync('demo.py', [], { command: 'python3' })

2 部分 Windows 系统返回中文乱码

可设置 windowsEncoding 参数值为 'utf8',例如:

复制代码
await pm.executeAsync('demo.js', [], { windowsEncoding: 'utf8' })
相关推荐
衡石科技4 小时前
一个门户只保留一个智能助理:衡石嵌入式 Data Agent 的运行与渲染边界
前端·javascript·html·data agent
Hilaku4 小时前
一个前端工程师除了写代码,还能靠什么赚钱?
前端·javascript·程序员
程序员Sunday4 小时前
JavaScript 闭包是什么?为什么变量没有被释放,什么时候会内存泄漏?
前端·javascript
JarvanMo4 小时前
Flutter 终于有自己的 React Flow 了,vyuh_node_flow 上手实录
前端
狂师4 小时前
爆火!新一代e2e AI测试框架,单日狂揽1500 star
前端·人工智能·测试
西瓜很甜哟4 小时前
golang实现大文件分片上传
后端·golang·html
恋猫de小郭4 小时前
Flitz ,一个把 Flutter 玩成热插拔 Preview 的有趣项目,不错的思路
android·前端·flutter
闭包不眠4 小时前
Word转HTML后体积不对,裁掉的截图原图还在
前端·图像处理·人工智能·计算机视觉·html·word
言乐64 小时前
PythonLOLM自动生成复盘报告模型
开发语言·前端·数据库·人工智能·python
tryCbest4 小时前
第二篇:CSS3 全部知识点全解 + 项目样式实现
前端·css·css3