极客手中的利器 Electron

作为一个前端开发人员,你可能已经听说过 Electron 了,你知道 VS Code 是基于这个技术开发的。不但 VS Code,目前一些大热的软件:飞书、Slack、WhatsApp 都是基于这个技术开发的。即使如此,这也并不足以引起你的重视,毕竟桌面软件式微,移动端和 Web 开发才是大方向,你的工作可能根本就不会涉及桌面开发领域的内容。但我想告诉你的是:

即使工作不会涉及到,也应该学一下 Electron,因为它是极客手里的利器,你可以通过他做很多 Amazing 的事情。

本文主要讲讲 Electron 是什么,以及它能做什么极客工作。

1

   

Electron 的由来

2011 年左右,中国英特尔开源技术中心的王文睿(Roger Wang)希望能用 Node.js 来操作 WebKit,而创建了 node-webkit 项目,这就是 NW.js 的前身。当时的目的并不是用这两个技术来开发桌面 GUI 应用。

中国英特尔开源技术中心大力支持了这个项目,不但允许王文睿分出一部分精力来做这个开源项目,还给了他招聘名额,允许他招聘其他工程师来一起完成这个项目。2012 年,故事的另一个主角赵成(Cheng Zhao)加入到王文睿的小组,并对 node-webkit 项目做出了大量的改进。

后来赵成离开了中国英特尔开源技术中心,帮助 github 团队尝试把 node-webkit 应用到 Atom 编辑器上,但由于当时 node-webkit 还并不稳定,且 node-webkit 项目的走向也不受赵成的控制,这个尝试最终以失败告终。

但赵成和 github 团队并没有放弃,而是着手开发另一个类似 node-webkit 的项目:Atom Shell,这个项目就是 Electron 的前身,赵成在这个项目上倾注了大量的心血,这也是这个项目后来广受欢迎的关键因素之一,再后来 github 把这个项目开源出来,最终更名为 Electron。

你可能从没听说过这两个名字,但开源界就是有这么一批“英雄”,他们不为名利而来,甘做软件行业发展的铺路石,值得这个领域的所有从业者尊敬(以上内容与 Electron 的作者确认过)。

2

   

注入脚本

Electron 内部拥有一个完整得浏览器核心,你可以用程序操纵这个浏览器核心,让它加载一个第三方网页,比如:淘宝的生意参谋、网易云音乐、gitee 等,但单单加载这些网页,并没有什么稀奇的,毕竟在浏览器里也能加载这些网页。最有意思的是,你还可以给这些网页注入脚本,比如像下面这样,注入一个 Js 文件到目标网页:

极客手中的利器 Electron

如果你只希望注入一两句代码,也可以通过如下形式注入脚本:

极客手中的利器 Electron

这些脚本是在目标网页的作用域下执行的,与目标网页的工程师自己写的代码没什么区别。想象一下,你如果想调用目标网页的某个服务端接口,你是不是应该考虑如何模拟 token,如何跨域等等问题,现在你只需要在脚本里直接写调用接口的逻辑就可以了。

另外,如果你不喜欢目标网页的页面样式,你也可以直接注入一段样式脚本,代码如下:

极客手中的利器 Electron

值得一提的是,你注入的脚本还可以访问 Node.js 的 API。也就是说,你在脚本中获取到了目标网页的资源后,可以直接写到你本地文件里。

3

   

突破同源策略的限制

注入了脚本,获取到了受限的资源,你可能希望把这些资源提交到你自己的服务器上,或者你可能希望在注入的脚本里,访问另一个网站的 API,以获取更多的资源,这个时候,如果没做特殊配置的话,同源策略就会起作用,限制你这么干,浏览器往往会报如下错误:

极客手中的利器 Electron

“同源策略”是浏览器的一个安全功能,“同源”是指如果两个页面的协议(http/https)、端口和主机都相同,则两个页面具有相同的源。同源策略规定不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。只有同一个源的脚本才具备读写 cookie、session、ajax 等的操作的权限。

在 Electron 中突破同源策略,就是一两个配置的事情,代码如下:

极客手中的利器 Electron

这样设置之后,浏览器的所有同源策略限制就全部失效了。如果你只是希望在 https 域下访问 http 的资源,那么你可以不用关掉整个同源策略,只需要把 allowRunningInsecureContent 这个配置设置为 true 即可(它同样也是 webPreferences 下的一个属性)。如果你设置 webSecurity 为 false 了,那么 allowRunningInsecureContent 会自动设置为 true。

4

   

读写受限访问的 Cookie

由于浏览器每次与服务端的交互,都会携带同域下的所有 Cookie,所以网站开发者往往会把标记用户身份的信息(比如用户 token)放到 Cookie 里。

一般情况下,前端开发工程师可以使用 document.cookie 访问浏览器里存储的同域的 Cookie,但也有例外,凡标记了 HttpOnly 的 Cookie,通过这种方式都是访问不到的。网站开发者之所以这么做,主要是为了防止跨站脚本攻击(XSS)和跨站请求攻击(CSRF)。

跨站脚本攻击(XSS,是 Cross Site Scripting 的缩写),一旦网站允许用户提交内容,并且会在网站的某些页面上显示用户提交的内容,比如留言或者博客,那么不做防范的话,就有可能受到跨站脚本攻击。恶意用户会在提交内容时在内容中夹带一些恶意 JavaScript 脚本,当其他用户访问页面时,浏览器会运行这些恶意脚本,恶意脚本有可能会窃取用户的 Cookie、页面上的用户隐私信息等,并发送到恶意用户的服务器。他们可以通过这些窃取来的信息模拟用户身份完成非法操作。这就是跨站脚本攻击。

跨站请求攻击(CSRF,是 Cross Site Request Forgery 的缩写),当用户登录了自己信赖的网站后,用户身份信息(token)会被保存保存在用户的浏览器上,后来用户又不小心打开了一个恶意网站,这个恶意网站可能会要求浏览器请求用户信赖的网站(通过 iframe 等形式),如果用户信赖的网站没有做安全防范的话,可能会被恶意网站获取到用户的敏感信息(token),从而给用户带来伤害。

但这个限制在 Electron 面前也不值一提,我们可以通过下面这种方式读写受限访问的 Cookie:

极客手中的利器 Electron

通过这种方式,无论 Cookie 有没有设置 HttpOnly 属性,都可以成功读写。

5

   

转发/修改请求

有的时候你不单单是希望给第三方网页附加代码逻辑,而是希望侵入式的修改第三方网站自身的代码逻辑。但往往第三方的 JavaScript 代码是在一个闭包作用域内执行的,你的代码没办法注入到这个作用域内,去访问作用域内的变量或方法,碰到这样的状况该怎么办呢?

此时,你第一步要做的,就是分析清楚它的脚本是如何执行的,是哪个脚本文件执行的。这个过程是一个非常有趣的过程,不可避免的你要用到谷歌浏览器的开发者调试工具,如果对方的代码是压缩过的,你可能还要给它“美化”一下,再逐步调试。

搞清楚逻辑之后,就把他的脚本文件下载下来,然后在这个文件中加上你的逻辑,你的逻辑可能就是粗暴的把它闭包作用域内的变量暴露到 window 对象上。这样你注入的脚本,就可以访问这个变量了。

修改完这个脚本文件后,把这个脚本文件 host 到你自己的一个服务器上,然后通过 Electron 把网页加载这个脚本文件的请求,转发到你自己的服务器上去,这个转发请求的代码如下:

极客手中的利器 Electron

当这个网页再试图加载这个脚本时,得到的结果将是你修改过的脚本。

有些网站对一些敏感数据保护的很好,客户端请求这些数据时,得到的是服务端加密过的数据,客户端执行解密后,再使用这些数据。对于这类网站,Electron 的这个能力无疑是非常有力的。

当然,你也可以考虑使用 PWA 技术里的 service worker 来办这个事儿,甚至可以自己在客户端模拟一个响应,不用再经由你的服务器转发了。如果你没有自己的服务器,也可以通过 Node.js 的能力,自己在软件里起一个 localhost 的服务。所有这些骚操作,都必须时在 Electron 内执行的哦。

6

   

反“防盗链”

有的时候你可能只是想把目标网站的一些静态资源嵌入到你的应用程序中,比如:图片或者视频。然而如果目标网站已经做了防盗链的工作,你这个功能可能就没那么容易实现了。

防盗链的主要目的有两个:一个是版权问题,别人未经授权就使用你的资源,另一个是流量压力的问题,盗链产生了大量的请求,这些请求对于网站运营者来说没任何价值。

防盗链最常见的做法就是识别 HTTP 的 Refer 请求头,这个请求头代表着发起请求时前一个网页的地址,网站运维工程师会根据这个 Refer 请求头来推测出当前请求是否为一个盗链请求(判断这个 Refer 请求头的内容是不是自己域名下的一个地址)。

Electron 允许开发者监听发起请求的事件,并允许开发者在发起请求前修改请求头,我们可以在这个事件里修改这个 Refer 请求头,代码如下:

极客手中的利器 Electron

7

   

给应用植入 socks5 代理

Chrome 本身是支持代理的,使用 Electron 你可以通过编程的方式把你的代理内置到你的应用程序中,这样你的用户就可以自由的访问国外的一些网站了:

常见的代理服务器有 http 代理、https 代理和 socks 代理,socks 代理隐蔽性更强,效率更高,速度更快。咱们这里就聊聊如何在 Electron 应用内植入 socks5 代理访问网络服务。

极客手中的利器 Electron

上面代码中,我们使用 session 实例的 setProxy 方法来为当前页面设置代理,socks 代理,代理设置成功后,我们马上使网页加载了一个 IP 地址查询的网址,在此页面上我们可以看到访问该页面的实际 IP 地址,如果这里显示的地址是你的代理服务器的所在地的地址,那么说明代理设置成功。

以上这种方法可以给单个渲染进程设置代理,如果你需要给整个应用程序设置代理,可以使用如下代码完成:

极客手中的利器 Electron

8

   

最后

极客手中的利器 Electron

以上内容来自于《Electron 实战:入门、进阶与性能优化》,这本书是我的好友刘晓伦写的,我也读了,确实写的不错,想推荐给大家,书里还有更多有趣的内容,大家感兴趣可以加 QQ 群 949674481 交流。书籍购买地址:

京东:https://item.jd.com/12867054.html

当当:http://product.dangdang.com/28547952.html

最后是福利时间:好久没给大家送礼物了,今天搞个抽奖,给大家送 8 本《Electron 实战:入门、进阶与性能优化》,大家在公众号对话框里回复关键字:Electron ,即可扫码参与抽奖,没有乱七八糟的条件,参与后,随机抽取。

另外,我的视频号开始更新了,大家可以关注我的微信视频号,每天分享一条有价值的视频,让你的生活「有点意思」

极客手中的利器 Electron

--- 特别推荐 ---

特别推荐:一个新的优质的推荐高效工具,软件,插件的公众号,每天给大家分享优秀的效率工具,「程序员掘金」,专门为程序员挖掘好东西的一个公众号,非常值得大家关注。

极客手中的利器 Electron