前一段时间在作者群里大家讨论,萌生了写个油猴脚本的想法,主要作用是给页面上增加一些好玩的功能。在写脚本的过程中,重新整理了一些关于油猴脚本的信息,也就有了本文。▍油猴脚本:是什么、能干嘛?
油猴脚本,正式的叫法是用户脚本(user script)。之所以叫做「油猴」,是因为第一个制作这个浏览器扩展的作者 Aaron Boodman 起名叫做 Greasymonkey,中文直译就是「油腻的猴子」;后面其他脚本开发的时候,基本都在沿用 Greasymonkey 的一些基本规范,这些脚本也就统称为「油猴脚本」了。你可以将用户脚本理解为一种可以根据我们的实际需求,为网页「加料」的手段。如果你之前从来没有使用过用户脚本又想体验一下的话,可以按照以下步骤操作来快速感受一下它的魅力:- 下载浏览器扩展,绝大部分情况下我都推荐 Tampermonkey,根据你使用的浏览器, 可以访问并安装:
找到脚本源,这里我把一个脚本发布在了 Greasyfork 上,大家可以在 https://sspai.com/s/RkNX 查看。页面中有一个绿色的安装按钮,点击就可以了。
安装好之后,访问任意作者文章页面,在右侧的「成就与徽章」这一部分,你就可以看到多出来了一个新的部分。如果这个作者太长时间没有更新,就会出现个红色的字体激励作者去写稿哦。虽然这个脚本非常简单,但是看到这里,你已经了解了用户脚本最核心的功能了。▍用户脚本的历史与不同版本
最早的时候,Firefox 火狐浏览器向开发者开放了扩展的能力,所有的开发者可以在火狐浏览器开放的能力内开发一些新的能力。2004 年底,Aaron Boodman 在看到另一个用于精简网页的扩展的时候,想到了这个绝妙的点子,随机在 2005 年初发布了最初的 0.25 版本Greasymonkey。很快,大家就想到了通过 Greasymonkey 写一些用于屏蔽广告的脚本(这个习俗到现在都还有),但也被一些广告主吐槽。不过后面等到 ADblock 上线之后大家就转而去喷这一类扩展了。到了 2010 年,随着 Chrome 浏览器高歌猛进,另一位作者 Jan Biniok 开发了 Chrome 版本的用户脚本管理器扩展,起名叫做 Tampermonkey,直译应该叫做「篡改的猴子」。我个人觉得这个名字比 Greasymonkey 更贴切一些,符合用户脚本的实际作用。到目前为止,Tampermonkey 已经有超过千万的用户下载使用了,评分也非常高,是目前平台支持最完整的用户脚本扩展。Tampermonkey 在权限控制、脚本编辑和调试、全局黑白名单这些方面都做得相当不错,易用性相比 Greasymonkey 提升了不少。Tampermonkey 的 Chrome 扩展界面而 2013 年 Violentmonkey「暴力猴」的上线又解决了两个痛点:其实 Greasymonkey 也是开源的,但到 Tampermonkey 诞生的时候并没有选择开源,而是以捐献软件的形式出现,这一点挺多人比较在意。暴力猴迭代到现在,也更新了非常多版本,支持的平台已经覆盖了所有主流的浏览器平台,不过界面上还是比较简单。Violentmonkey 的 Chrome 扩展界面这几款主流的浏览器扩展的支持情况见下表,如果有不当请留言指正。▍用户脚本的原理浅析
当然了,如果要用严谨一点的定义来说,用户脚本其实是一种注入式的 JavaScript 程序,在网页本身的程序之外,通过一些手段,将用户需要的数据和逻辑注入到当前的网页中,达到修改界面、增加功能等等的目的。换句话说用户脚本也是 JavaScript。JavaScript 能实现的能力,用户脚本基本也能做,比如操作页面元素,可以给页面中增加、删减、修改页面元素,最常见的去广告脚本就是这么实现的。不过用户脚本能提供一些普通 JavaScript 实现不了的能力。Greasymonkey 在最早的 0.25 版本中就带来了两个基本的功能:这两个功能到现在为止仍然非常核心,这里稍微解释一下背景。跨域请求
为了安全起见,浏览器在页面加载的时候会有一个同源策略,如果页面中的 javaScript 来自另一个域名,浏览器就会认为这个不安全不让其加载运行,但有的时候用户可能会有一些别的需求。举个例子:比如说在京东或者当当上买书的时候,想看一下豆瓣上用户的评分,这种情况下就需要用到用户脚本的这个能力了。在京东的页面中,我们就可以借助用户脚本调用这个 GM_xmlhttpRequest 的 API 去访问豆瓣平台的查询接口。菜单操作
很多情况下,用户脚本不需要自动执行,而是需要使用者来手动运行,这时就需要 GM_registerMenuCommand 了,在点击之后,触发一个写好的函数,就可以完成改变页面数据,或者发起某些请求的情况。举个例子:我在页面中看到一个不认识的单词,想要查询一下,这时候选中这个单词,然后触发这个接口,就可以实现查询的效果(当然也有很多的别的能力可以实现划词查询)。除了这两个功能之外,目前的用户脚本,大多采用了 Greasemonkey 制定的 V4 API 规范。通过这个规范,我们就能知道用户脚本可以做什么了。在 V3 版本的 API 中,还多了几个能力,包括:不过上述的几个用户脚本扩展也出现了一些自己的差异,比如 Tampermonkey 就支持了插入节点的能力,也支持获取当前标签页面信息的能力。如果你是一个用户脚本开发者,需要注意一下这些差异点。▍从哪里获取用户脚本
指望每一个人都去自己写脚本是不现实的,这需要大家有一些基本的前端开发能力。大部分的用户都是去找一些现成的脚本来使用,这就是所谓的「脚本源」。最早期的脚本源,最有名的是 userscript.org 站点,不过由于维护不力,导致后面充斥着各种各样的有害脚本,非常影响大家使用。目前这个站点已经下了,我也没有给它加上可以点击的超链接。如果你想体验,可以访问 https://userscripts-mirror.org/ 这个链接来找到之前的老脚本。当然,直接在 GitHub 上去找脚本也是个不错的选择。
在上面提到的划词翻译这个例子中我们其实引入了这样一个问题:同样一个需求,如果浏览器扩展和用户脚本都能实现,我们应该如何选择?一方面,浏览器扩展相比用户脚本诞生的时间其实更晚,各家的浏览器扩展后发制人,的确也有了比用户脚本强得多的功能实现;但另一方面,虽然脚本能力有限,但是它们占用的系统资源和内存又更少一点。另外,从安全性角度上来说,用户脚本虽然也爆出过不少窃取个人信息、替换返利链接甚至挖矿的负面新闻,但用户脚本的源代码审查相比浏览器扩展更为直接透明,选择合适的用户脚本获取渠道、留意脚本的权限请求,有基础的用户也可以多多留意、检查脚本内容,一般就能规避大部分风险。因此我自己的解决方案是,对于轻量一些的场景,通过用户脚本 + 用户样式(user style)解决大部分浏览需求,重一些的场景则会选择浏览器扩展。当然了,如果你的设备对保密性和安全等级有着较高的要求,我还是不建议你安装任何用户脚本。▍结语
用户脚本作为一个 17 年前的互联网老古董,现如今仍有自己的用武之地,还是十分令人感慨。但作为油猴使用指南的第一期,本文仅为增加大家对「油猴脚本」的一点了解,如果你想解锁用户脚本的全部实力、甚至自己动手制作用户脚本,还请留意本系列的后续内容更新。