解锁JSA潜能:如何安全地利用JavaScript生态库 点击使用AI助手 了解更多
发布于 2024-11-24 liusiyang 4 编辑
JSA的功能有多弱,用过的人都知道,虽然它可以使用上javascript这样的现代语言,相比古老的VBA也好用不少。但现代语言不止于语言本身,还更重要的是其生态,大量的轮子库才是大家想用它的原因,给你使用python的原生功能,不含轮子库,我能说python是最差的现代语言。
所以当务之急是:让JSA能够用上现代轮子库才是关键。
有什么办法可以做到呢?前期有人实践过,直接把某个js轮子库的代码复制粘贴到某个模块里,是可行的。但因为JSA编辑器的简陋,也不支持超长的字符串,一粘贴就直接死机挂掉了。
在研究如何让RPA更好地调用JSA的过程中,灵机一动,可以使用javascript的动态语言特定,直接将写好的代码,保存为字符串,然后使用eval函数执行它,岂不就可以了吗?
经过测试,果真可以,详见以下代码,调用过程中,用了base64来转换,如果外部调用就很有必要防止一些特殊字符传输中异常,内部的话,应该不用转都行。
有了这个阶段性胜利后,笔者在想,既然能够eval一些代码段,那eval整个轮子库应该也行吧。因为已经测试到前面代码段里,其实已经在里面嵌套了一些函数都仍然可行,轮子库的本质也就是很多函数的封装,最后暴露一个上层方法供调用。
将一个js轮子库的内容,保存到一个字符串变量中,直接eval一下,就可以类似html的head里的定义的script节点效果一样,把它加载完就可以在接下来的代码里调用了。
笔者首先想到了,虽然在Excel/WPS表格里,一个单元格的能容纳的字符串长度有限制,最多32677个字符,那我用多个单元格来存储,再到JSA里重新拼接,不就可以了?而且在xlam加载项里,还天然地可以访问一个隐藏的工作薄,里面任意放多少内容都可以。
所以就立马开工,改造了一下原来的自定义函数,增加了一个GetFileContentsByItemLength函数(在Excel催化剂里可自动更新同步最新版下来,可在公众号后台回复:插件下载,获取最新版下载地址)。可以获取文件内容超过一个单元格最多容纳字符,以多个单元格方式存储。
只要在JSA里,读取这个连续单元格区域,再将它重新连接起来,就可以在eval方法里运行,如下图,加载完lodash库后,就可以执行它的方法如: _.concat。
有了上面的成果后,笔者再异想天开一下,既然JSA近期已经支持了网络访问功能,有xmlhttpRequest和fetch这些函数可以访问网络资源,而通常js库都是CDN加速过的,性能非常好的,所以何不直接从网络上获取到js库的代码,然后运行呢?结果还真可以。不过涉及到网络请求,是异步行为,琢磨了好久(主要是不熟),才跑通了,代码如下:
总结
本篇核心是使用eval来执行javascript代码字符串,虽然从正统上来说,不是太安全。但无奈WPS官方不作为,一直拖拉着,不出官方版本。
其实对于普通用户来说,安全是相对的,有时反而这些所谓的安全而阉割或拦阻一些作法,让一些好的idea不得不放弃。
所以既然已经授权定制化开发,既然交付了源码,有合规的专业背书,能够短平快完成一件复杂事情,这些所谓的安全,也不足以惧怕,所以本篇让JSA再次腾飞无限扩展JSA的边界,用上javascript的生态轮子库还是很有推广价值。
原文链接:https://bbs.wps.cn/topic/36293