Gear 浏览器对于「油猴」脚本的技术实现原理

2020-08-06 11:46:29 +08:00
 catfan

自从 5 月发布了里程碑 2.0 版本后,直到差不多三个月的现在已经发布了大大小小共 14 个版本。进行了大量的改进和修复,同时也有不少新的功能。由于 Gear 的几大核心功能一直都没有详细介绍,在此公开一些内部实现的原理,以方便大家了解。

油猴脚本

直到目前为止,Gear 依然是 iOS 首个支持油猴脚本的浏览器。有部分人认为一些浏览器支持执行 JavaScript 脚本代码就是所谓支持插件。事实上支持油猴脚本和支持 JavaScript 脚本其实是两回事。

在 iOS 上实现在页面加载前注入 JavaScript 脚本其实就是两行代码的问题。只需要调用:

let userScript = WKUserScript(source: String, injectionTime: WKUserScriptInjectionTime, forMainFrameOnly: Bool)
    
webView.configuration.userContentController.addUserScript(userScript)

文档:Apple Developer Documentation

核心就是第一行代码,第一个参数就是要注入的 JavaScript 代码,第二个是注入的时间,可选 atDocumentStartatDocumentEnd,第三个是是否只针对主 frame 执行。

就这,其实只需要几分钟的时间就能让 Web 浏览器实现执行 JavaScript 脚本(插件)的能力了。

但是,支持油猴脚本却是更加复杂的问题了。绝大部分油猴脚本都是无法通过此方式直接执行的。


首先,油猴脚本的头部注释配置定义了该脚本的执行环境、引入外部文件(如各种框架、数据、图片等)、权限授予、接口授予、以及各种相关信息。必须对此信息进行解析和保存,并在执行的时候配置好对应的代码执行环境。

还要给每个脚本配备独立的数据存储方式,不能和页面的共享。同时还要解决资源跨域访问等问题。

// ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        http://example.com
// @require      https://cdn.staticfile.org/jquery/3.3.1/jquery.js
// @resource     count  https://greasyfork.org/scripts/by-site.json
// @connect      translate.google.com
// @run-at       document-idle
// @grant        unsafeWindow
// @grant        GM_addStyle
// @grant        GM_getValue
// @grant        GM_setValue
// ==/UserScript==

(function() {
    'use strict';

    // Your code here...
    console.log("Hello World");
})();

以上是一个简单的油猴脚本代码。


其次,事实上目前桌面浏览器主要是这三大扩展支持执行用户脚本。而「油猴」只是其中一个的名字。

GitHub - greasemonkey/greasemonkey: Greasemonkey is a user script manager for Firefox.

GitHub - violentmonkey/violentmonkey: Violentmonkey provides userscripts support for browsers.

GitHub - Tampermonkey/tampermonkey: Tampermonkey is the most popular userscript manager.

Greasemonkey 主要对应 Firefox,而 Tampermonkey (目前最新已经不公开源代码,非开源)主要对应 Chrome 或基于 Chromium 的浏览器。它们内部都有不少地方调用了浏览器的内部接口来实现一些特殊功能。所以 Tampermonkey 也比较好移植到 Android 上。

有兴趣的,可以阅读其源代码,看看是如何实现的。

而在 iOS 上,是无法直接使用以上任何一个项目的代码来实现油猴脚本的支持。在思考了各种方案后,最终 Gear 则是选择了完全重新写一个脚本引擎来进行支持。

目前 Gear 选择的是通过 messageHandlers 来实现页面 JavaScript 与 Swift 原生代码进行数据的处理和通讯。例如跨域请求、数据存储等。并使用了缓存的方案,来加速脚本的加载和执行。原理上执行的效率会比单纯的移植高。而且还为此设计了一套 UI 交互来实现脚本的管理与安装等。于是你现在在 Gear 上可以在安装 Bilibili Evolved 这类的脚本来看 B 站,并使用各种特殊功能了……

当然,由于 Gear 的脚本引擎是完全自己开发的,并且还要同时兼顾 Greasemonkey 和 Tampermonkey 脚本的情况,所以目前还有一些接口还没有完全支持。

而且各个脚本代码的质量不一,各种奇怪的代码写法、各种代码重写、错误的引用、动不动就加载十几 MB 框架文件的情况等等,只能逐行代码来调试脚本。

目前 Gear 依然会不断对引擎进行升级来增强其兼容性。现在依然保持每隔一到两周进行一次更新,每次都会带来新的功能和实质性的改进。

如果在使用脚本过程中发现有问题,也可以直接反馈到 contact@gear4.app 。我这边会逐个进行测试和修复,尽量让其能在 Gear 运作正常。

下面送出一堆免费使用一个月 Gear Pro 的兑换码:

A6TTJNMX3RKE
PK6TXEH36P6W
6MA339K3FERP
MF6H9FPJXXEA
R3TWK6X3MA63
EPXKNHTF7F4W
TPJLW9XFYT4H
TPWXPLKALJT4
4YNA9YRYN97M
EMREJNE4KPFY
JAJFWMFAAEW7
LKMFRHN7WPEL
WRM49X6F3YEE
AX6LKMNHHHYP
N6ERJATNK7NM
36XX9F7WMWJR
ANTHJEK9HYX6
LHKPXXJ9RPAM
WWY3JTNAEYXJ
RHF4FEJYY9WH

PS:如果你是油猴脚本的开发者,可以发邮件到 contact@gear4.app 联系,只要你的邮箱地址和脚本的 author 信息相符,即可直接获赠免费使用一年 Gear Pro 的兑换码。


Gear 官网:https://gear4.app

App Store: https://apps.apple.com/cn/app/gear-browser/id1458962238?ls=1

7907 次点击
所在节点    分享创造
26 条回复
IceFinn
2020-08-10 10:32:41 +08:00
感谢喵大(⁎⁍̴̛ᴗ⁍̴̛⁎)
dullwit
2020-08-15 21:26:32 +08:00
反馈下问题
1. 在 iPad 小屏模式下,选择菜单键只显示了蒙层
2. 在 iPad 小屏模式下,网页内容不能识别为移动模式
3. 在手动选择内容模式后,输入新的网页后网页内容又会切换成自动模式
catfan
2020-08-16 09:26:47 +08:00
@dullwit 感谢你的反馈。你所说的应该是 Split View 分屏浏览吧。确实还没有做此模式的适配,之后会对此进行优化。

内容模式是对当前网站(域名)进行设定的,并且下次打开还会使用此设定,毕竟每个网站最佳浏览模式都不一样。
dengxufan
2020-08-16 12:29:25 +08:00
感觉很棒
fengshuo211
2020-08-17 09:12:53 +08:00
可以多讲一下脚本引擎嘛,ios 上不是只能用 webkit ?
justin2018
2020-08-17 15:17:40 +08:00
我好找就买了 哈哈哈 一直没用 昨天才在历史记录看到的 😁

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/696099

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX