大家好,今天分享一种远程调用 JS 代码的技巧,学会了它就可以弃用 pyexecjs 了。
pyexecjs现状
pyexecjs 在 2018 年已经停止更新了,虽然现在还可以使用,不过只有一些简单的脚本还可以用用,遇到复杂的脚本可能会有不兼容的情况。
![image-20250412125952927]()
![image-20250412130026304]()
![image-20250412130043242]()
![image-20250412130108653]()
而且 pyexecjs 底层其实就是封装了 Popen
类,在不同的 JS 环境中使用不同的命令运行对应的 JS 脚本,每次需要执行 JS 时,都要新建一个进程。而进程的创建在操作系统看来是一个比较重的操作,从效率上来说还是比较低的。接下来分享一种更加高效并且易于使用的方法来远程调用 JS。
远程调用 JS
这个方法就是使用 nodejs
的 express
框架来实现一个简单的 http
服务器,利用 require
关键字导入扣好的代码,然后启动服务器即可。
来看一个示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| const express = require('express'); const app = express(); const bodyParser = require('body-parser'); const match6 = require('../match/match6/code');
app.use(bodyParser.json({limit: '50mb'})); app.use(bodyParser.urlencoded({limit: '50mb', extended: true})); app.use(bodyParser.json());
app.post('/match6', (req, res) => { let result = req.body; if (!result.p) { return res.status(400).json({error: '参数缺失'}); } let data = match6(result.t.toString(), result.p); const responseData = {data: data}; res.set('Content-Type', 'application/json') res.json(responseData); });
app.listen(8919, () => { console.log("开启服务,端口8919", new Date().toString()) })
|
通过 require
关键字导入所需要的代码,并且在路由中调用。当然了,这个脚本作为 demo
使用没有问题,但是要在生产环境中使用需要考虑更多的情况,例如鉴权,动态更新,速率限制,并发操作等等。
沙盒
当然了,上面的示例使用的是 nodejs
本体执行扣好的 JS 代码,如果遇到那种会检测 nodejs
的,需要使用沙盒来运行 JS,否则它会导致 web
服务器启动失败的,之前我就遇到过一次。
在沙盒中运行 JS 的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| const express = require('express'); const app = express(); const bodyParser = require('body-parser'); const vm = require('vm');
const match14 = require('../match/match14/code');
app.use(bodyParser.json({limit: '50mb'})); app.use(bodyParser.urlencoded({limit: '50mb', extended: true})); app.use(bodyParser.json());
app.post('/match14_eval', (req, res) => { let result = req.body; if (!result.js) { return res.status(400).json({error: '参数缺失'}); } const sandbox = { window: {'href': 'https://match.xxxxx.cn/match/14'}, atob: (str) => Buffer.from(str, 'base64').toString('binary'), btoa: (str) => Buffer.from(str, 'binary').toString('base64') }; try { vm.createContext(sandbox); vm.runInContext(result.js, sandbox); } catch (e) { return res.status(500).json({error: '代码执行失败', details: e.message}); } let t8 = Date["parse"](new Date()) * 8; let t = Date["parse"](new Date()); let data = match14(t8, t, sandbox.window['v14'], sandbox.window['v142'], result.page) const responseData = {data: data}; res.set('Content-Type', 'application/json') res.json(responseData); });
app.listen(8919, () => { console.log("开启服务,端口8919", new Date().toString()) })
|
在沙盒中运行的 JS 脚本,不会污染现有的 nodejs
环境,也能避免执行到一些危险的脚本危害自己的系统。
总结
以上就是远程调用 JS 脚本的方法了,后续在执行 JS 代码时,只需要发送 http 请求并且填入参数,即可获得 JS 脚本的运行结果,感兴趣的小伙伴可以试一下。该方法的稳定性和效率都比较高,如果遇到那种耗时很久才能返回的 JS,也可以增加多个服务和负载均衡,做成一个小小的微服务。
本文章首发于个人博客 LLLibra146’s blog
本文作者:LLLibra146
更多文章请关注公众号 (LLLibra146):![LLLibra146]()
版权声明:本博客所有文章除特别声明外,均采用 © BY-NC-ND 许可协议。非商用转载请注明出处!严禁商业转载!
本文链接:
https://blog.d77.xyz/archives/undefined.html