sdenv-ng
v0.2.0
Published
下一代补环境框架
Readme
sdenv-ng是一个javascript运行时补环境框架,与github上其它补环境框架存在较大区别,sdenv-ng是站在巨人的肩膀上实现的,依赖于jsdom的强大dom仿真能力,sdenv-ng可以真实模拟浏览器执行环境,作者在固定随机数与添加sdenv-ng-extend的部分插件后可以达到瑞数vmp代码在sdenv-ng运行生成的cookie值与浏览器生成的cookie值一致。
- sdenv-ng专用jsdom版本:sdenv-ng-jsdom
- sdenv-ng多端环境提取:sdenv-ng-extend
- 对瑞数算法逆向可参考项目:rs-reverse
依赖
作者开发时使用的是v20.10.0版本node,预期最低要求是18版本,由于未做其它版本可用性测试,因此建议使用sdenv-ng的node版本大于等于v20.10.0。
编译node插件用的是node-gyp工具,该工具需要有python环境和c环境(如windows系统需安装Visual Studio,Mac系统需要安装XCode),请根据工具文档进行系统环境搭建。
需要注意windows中安装Visual Studio时需要勾选使用C++的桌面开发选项

可能出现的问题
- npm安装node-gyp报错:请确保操作系统有c++编译环境与python环境,报错示例(感谢用户风流小混沌提供图片素材):

- 安装缓慢及canvas报错:由于canvas安装会优先从github获取现成的包,因此请在安装前先设置代理或者其它国内源,如果安装仍然失败请使用npm官方源+代理方式重新尝试;
解决完报错后记得重新执行下依赖安装!
有其它问题请提issues!
使用
npm包使用
- 创建自己的项目
- 项目中安装sdenv-ng:
npm i sdenv-ng(请确保安装没有报错) - 在项目中导入api并使用(可以参考example目录下的用例):
const { jsdomFromText, jsdomFromUrl, browser } = require('sdenv-ng');样例代码运行
注意:样例代码仅供参考,作者建议使用npm包方式使用sdenv-ng框架!
源码方式
clone项目仓库后执行依赖安装npm i,确保依赖安装成功后即可运行example目录下的样例文件了。
- 运行本地代码:use-local

- 运行网站代码:use-remote

docker方式
提供docker方式运行样例代码.
首先执行uname -a后查看架构类型,支持arm64和x86_64
如果是arm64架构则执行命令:
- 运行本地代码:
docker run --rm pysunday/sdenv-ng:arm64 ./example/use-local/index.js - 运行网站代码:
docker run --rm pysunday/sdenv-ng:arm64 ./example/use-remote/index.js
如果是x86_64架构则执行命令:
- 运行本地代码:
docker run --rm pysunday/sdenv-ng:x86_64 ./example/use-local/index.js - 运行网站代码:
docker run --rm pysunday/sdenv-ng:x86_64 ./example/use-remote/index.js
docker打包
可以参考项目的Dockerfile.example文件,通过命令uname -a查看架构类型,然后取消对应的FROM语句注释,修改文件名为Dockerfile,如arm64架构的Dockerfile文件内容:
FROM pysunday/sdenv-ng_base:arm64
RUN git clone https://github.com/asdw741111/sdenv-ng-ng.git
WORKDIR /sdenv-ng
RUN npm i
ENTRYPOINT ["/usr/local/bin/node"]最后执行命令docker build -t pysunday/sdenv-ng ./生成容器
运行容器内的样例代码与前面类似:
- 运行本地代码:
docker run --rm pysunday/sdenv-ng ./example/use-local/index.js - 运行网站代码:
docker run --rm pysunday/sdenv-ng ./example/use-remote/index.js
如果需要在docker内调试代码,作者建议使用npm包的方式使用sdenv-ng,然后通过映射方式调用docker
API
sdenv-ng设计极其简单,它的核心API只有一个,即browser!
browser(window: object, type: string)
传入window对象,和需要拟真的浏览器类型,browser方法会自动将浏览器特性集成到window对象中。
const { browser } = require('sdenv-ng');
...
browser(window, 'chrome')浏览器类型及支持情况:
类型 | 是否支持 ---- | -------- Chrome | Y Firefox | N Safari | N
jsdomFromText(config: object)
返回回调方法,用于纯文本方式调用jsdom,第一个参数为配置对象,最终会作为第二个参数传入到jsdom中。
const { Script } = require("vm");
const { jsdomFromText } = require('sdenv-ng');
const [jsdomer, cookieJar] = jsdomFromText({
url: 'https://host/path',
referrer: 'https://host/path',
contentType: "text/html",
runScripts: "outside-only", // 不会执行html文本中的js代码
})
const dom = jsdomer('<html>...</html>');
new Script('javascript代码').runInContext(dom.getInternalVMContext()); // 执行javascript代码
console.log('cookie值:', cookieJar.getCookieStringSync('https://host'));进一步阅读:
jsdomFromUrl(config?: object, cookieJar?: CookieJar)
返回回调方法用于链接形式调用jsdom,第一个参数为配置对象,与jsdomFromText方法不同,该配置对象用于配置ResourceLoader,建议至少传入ua值,否则请求header中的ua内容会有jsdom标识,需要注意的是,该ua仅在jsdom层使用,cookieJar非必传,当需要延续cookie时需要传入。
const { jsdomFromUrl } = require('sdenv-ng');
const config = { userAgent: 'native browser userAgent' };
const [jsdomer, cookieJar] = jsdomFromUrl(config); // 返回自动生成的cookieJar
const oneDom = await jsdomer('https://host/path');
const twoDom = await jsdomFromUrl(config, cookieJar)[0]('https://host/path'); // 使用已经存在的cookieJar,因为要沿用上一次产生的cookie
console.log('cookie值:', cookieJar.getCookieStringSync('https://host'));进一步阅读:
sdenv-ng-extend使用说明
为了模拟浏览器执行环境,需要将node环境与浏览器环境共有代码进行提取,并提供返回环境对象用于sdenv-ng内window与dom内容补充使用。
sdenv-ng-extend具体功能可参考项目内README文档。
sdenv-ng-jsdom使用说明
sdenv-ng-jsdom包是sdenv-ng补环境框架能运行瑞数vmp网站并产生正确cookie的核心,该包仓库fork自jsdom仓库,并应对瑞数vmp对jsdom的检测做了代码修改,因此sdenv-ng可以过网站对jsdom的检测!
和sdenv的区别以及开发计划
sdenv更新较慢,不便于添加更多功能,并且基于Jsdom版本过旧所以重新开发一个框架。
目前的区别:
utils\jsdom.js修改,支持传入ResourceLoader便于自行控制资源内容。
计划:
- [ ] 1. jsdom升级到最新版本
- [ ] 2. 整合sdenv-extend便于统一维护。
- [ ] 3. TODO
