aardio封装库) 微软开源的js引擎(ChakraCore)

打印 上一主题 下一主题

主题 875|帖子 875|积分 2625

媒介

做爬虫肯定少不了JavaScript引擎的使用,比如在Python中现在一样平常用pyexecjs2来执行JavaScript代码,另外另有一些其他执行JavaScript的库:

  • https://github.com/eight04/node_vm2: rpc调用nodejs,需要安装node
  • https://github.com/eight04/deno_vm: rpc调用deno,需要安装deno
  • https://github.com/wistn/pyChakraCore: 调用ChakraCore.dll
aardio执行js

假如本地安装有nodejs,aardio范例里也有rpc调用node执行JavaScript的例子。
但是rpc调用需要依赖本地的nodejs环境,给别人使用也不方便,需要让人先安装nodejs。而ChakraCore这个微软开源的js引擎可以直接调用dll来实现,不需要额外依赖。以是这篇文章我来封装下aardio下的ChakraCore。
有了js引擎的话,又可以利用JavaScript优秀的库资源来丰富aardio的库。比如加载crypt-js给aardio增加一些加密算法(AES、DES等)。
下载地址

封装好的代码可以到github下载
下载地址:https://github.com/kanadeblisst00/aardio-extlibs
开始封装

仓库地址:https://github.com/chakra-core/ChakraCore
编译dll

仓库给出的编译好的dll文件还是2020年的,但是代码最近不停在更新,以是最好是自己编译一个,防止之前的有bug还没修复到。
根据官方给的文档,下载源码后使用vs2017打开Build下的Chakra.Core.sln,然后改一下编译的架构为x86。右键天生办理方案,一步就过了,没有什么坑(最喜好编译这种项目了)。

天生的dll文件在Build\VcBuild\bin\x86_release下,只需要ChakraCore.dll这一个文件。
封装思路

封装这个库用了不少时间,根本是参考上面pyChakraCore的代码。就不说具体怎么做的(无非就是参考Python的代码和看github和官方文档吗,碰到不会的在搜索一下),有爱好的可以自己看看库代码,下面说说怎么使用。
测试这个dll无法使用aardio的内存加载,也就是说打包的时候只能带上这个dll,不能直接打包进exe。
案例

说几个简单使用的案例,由于还没有深度使用,后面想到什么在增加吧
例子1
  1. import console;
  2. import ChakraCore;
  3. io.open()
  4. var core = ChakraCore();
  5. core.start();
  6. console.dump(core.run('(()=>{return Uint8Array.from([1,2,3,4]).buffer;})()'))
  7. console.dump(core.run('(()=>{let a = {"a":1,"b":2};return a;})()'))
  8. console.dump(core.callFunction('pretty', {"a":1,"v":"111"}))
  9. console.dump(core.run('console.log("aaaaa",undefined,null,false,{a:1,b:2},function(){})'))
  10. console.pause(true);
复制代码
例子2

先定义函数再调用
  1. import console;
  2. import ChakraCore;
  3. io.open()
  4. var core = ChakraCore();
  5. core.start();
  6. core.run("
  7.         function add(a,b){
  8.                 return a+b;
  9.         }       
  10. ")
  11. var a = 1;
  12. var b = 2;
  13. console.log("a+b=", core.callFunction("add", a,b))
  14. console.pause(true);
复制代码
例子3

注册aardio函数为JavaScript函数,这里以atob和btoa这两个函数为例,ChakraCore没有自带这两个函数,而浏览器有,以是我们用aardio来实现。我在库代码里已经内置了console.log和setTimeout,有爱好的可以自己看怎么实现。
  1. import console;
  2. import ChakraCore;
  3. import crypt.bin;
  4. io.open()
  5. var core = ChakraCore();
  6. core.start();
  7. var btoa = function(ptr_callee, isConstructCall, ptrj_arguments, argumentCount, callbackState){
  8.         // ptr_callee不知道是什么
  9.         // isConstructCall表示是不是构造方法
  10.         // ptrj_arguments是参数的数组
  11.         // argumentCount是参数的个数
  12.         // callbackState也不知道是什么
  13.         var pointerSize = 4;
  14.         var jStr = ..raw.convert(ptrj_arguments, {ptr p}, pointerSize).p;
  15.         var aStr = ChakraCore.jValueToString(jStr);
  16.         var result = crypt.bin.encodeBase64(aStr);
  17.         var jResult = core.JsCreateString(result,#result,);
  18.         return jResult;
  19. };
  20. var atob = function(ptr_callee, isConstructCall, ptrj_arguments, argumentCount, callbackState){
  21.         var pointerSize = 4;
  22.         var jStr = ..raw.convert(ptrj_arguments, {ptr p}, pointerSize).p;
  23.         var aStr = ChakraCore.jValueToString(jStr);
  24.         var result = crypt.bin.decodeBase64(aStr);
  25.         var jResult = core.JsCreateString(result,#result,);
  26.         return jResult;
  27. }
  28. core.registerMethod(btoa, "btoa");
  29. core.registerMethod(atob, "atob");
  30. var result = core.run('btoa("Hello, world")')
  31. console.log("btoa: ", result)
  32. console.log("atob: ", core.callFunction("atob", result))
  33. console.pause(true);
复制代码
而且比力有意思的是,这样注册的JavaScript函数打印出来的也是function () { [native code] },可惜和浏览器还是有区别,浏览器会加上函数名function btoa() { [native code] }
例子4

调用crypt-js实现下加密AES CBC加密算法
  1. import console;
  2. import ChakraCore;
  3. io.open()
  4. var core = ChakraCore();
  5. core.start();
  6. core.run($"~\lib\ChakraCore\.res\crypto-js.js")
  7. var js = /*
  8. let key = CryptoJS.enc.Utf8.parse("1234567890000000");
  9. let iv = CryptoJS.enc.Utf8.parse("1234567890000000");
  10. let s = "Hello World";
  11. let encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(s), key, {
  12.         iv: iv,
  13.         mode: CryptoJS.mode.CBC,
  14.         padding: CryptoJS.pad.Pkcs7
  15. });
  16. var eData = CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
  17. console.log("加密字符串: ", eData);
  18. let decrypted = CryptoJS.AES.decrypt(eData,key, {   
  19.     iv: iv,
  20.     mode: CryptoJS.mode.CBC,
  21.     padding: CryptoJS.pad.Pkcs7
  22. });
  23. let dData= decrypted.toString(CryptoJS.enc.Utf8).toString();
  24. console.log("解密字符串: ", dData);
  25. */
  26. core.run(js)
  27. console.pause(true);
复制代码
本文由博客一文多发平台 OpenWrite 发布!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

天津储鑫盛钢材现货供应商

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表