Skip to content

Instantly share code, notes, and snippets.

@Ancientwood
Last active July 5, 2021 01:59
Show Gist options
  • Save Ancientwood/6fbb88a661bd6f4f6b30ec82d1206155 to your computer and use it in GitHub Desktop.
Save Ancientwood/6fbb88a661bd6f4f6b30ec82d1206155 to your computer and use it in GitHub Desktop.
@Ancientwood
Copy link
Author

Ancientwood commented Jul 5, 2021

接口详解

unsafeWindow

这大概不能算是一个接口,但是 Tampermonkey 的文档中也把它列出来了。当脚本以 content 模式注入时,我们可以用这个对象来访问一些原本受限的内容。就如它的名字一样,使用这个方法意味着绕过了一些安全限制,也就有可能带来一些安全上的问题。

资源验证

这大概不能算是一个接口,但是 Tampermonkey 的文档中也把它列出来了,Violentmonkey 似乎并不支持此方法。

当我们引入一个资源,如何确定这个资源就是我们所预期的那个,而没有出差错,在请求的过程中没有被人替换掉。那么我们可以对引入的资源加入一个校验。

具体使用是在我们引入资源时,网址后面以井号分割的形式加入对应的校验特征码:

// @resource logo https://img3.appinn.net/static/wp-content/uploads/appinn190.png#md5=ad34bb...

Tampermonkey 本身支持 md5 方法,其它(SHA-1,SHA-256,SHA-384和SHA-512)资源特征方法,都取决于 window.crypto 的支持。

如果资源校验不成功,则不会传递给用户脚本。文档中说所有校验用的特征码都需要以十六进制或 Base64 格式编码,具体我未做测试。

一般的讲,这并不是很有必要,虽然确实在安全方面做得很到位。但是一般网站中的资源也都没有经过校验,目前对于资源的网址启用 https 已经可以杜绝大部分问题。

这个方法的主要问题是有的脚本管理器并不支持。不过因为附加的内容以锚点形式出现,所以并不会带来什么副作用,而且附带上文件的校验特征,也可以确保当此文件发生更新之后使用的是更新后的文件,而不是缓存。

以下以 GM_ 开头的这些方法才是相对正式的接口,如果需要使用,它们均需要在元数据用以 @grant 字段进行声明。

GM_info

这个方法可以用来获取一些有用的信息,但根据脚本管理器的不同,返回的内容也不太一样。不过一般都会包含脚本的元数据,脚本管理器的相关信息,系统环境的相关信息。

const info = GM_info()
console.log(info)

如果需要使用,可以像上面那样先输出出来,看一看它能够获取到的信息。下面列出一些其中比较通用的属性(Tampermonkey 和 Violentmonkey 中都有的):

  • scriptMetaStr: 脚本的元数据,整个元数据部分,以字符串形式返回。
  • scriptWillUpdate: 脚本是否会自动更新
  • scriptHandler: 脚本管理器的名称
  • version: 脚本管理器的版本
  • script: 脚本的元数据,以对象形式返回。其中包含的元数据可能因脚本管理器的不同而不同。@match 变成了 matchs,以数组形式包含全部的规则,其它可以出现多次的条目类似。@run-at 变成了 runAt,即避免产生歧义的驼峰写法。

GM_addStyle

向页面中加入样式,这个方法非常简单并且好用,只需要给它一串 CSS 的文本,它就会在文档的 <head> 标签中加入一个 <style> 标签,并把这些 CSS 的内容放进去。然后会返回这个 <style> 元素的对象。

一般来说, <style> 标签会被添加到 <head> 标签的最后面,以确保覆盖页面中原有的样式。但这个事情并没有绝对的保证,只是它在努力去做而已,所以想要确保自己的样式覆盖页面中原有的样式,还是要在 CSS 中添加 !important

听不太懂也没有关系,下面看示例代码:

GM_addStyle(`
	// 这里写 CSS 代码,可以多行
`)

复制上面代码,然后在中间添入你的 CSS 就行了。注意这里使用的是反引号,这被称为模板字符串,在其中可以进行换行,这样在里面书写 CSS 就可以带上清晰的格式,就像平时书写 CSS 文件一样。如果把其它地方复制过来的 CSS 粘贴进去,也无需因为是在 JS 中而调整 CSS 字符串的格式。

如果你有对这个 <style> 元素的对象进行进一步操作的需求,可以获取它的返回值。

GM_log

这个方法是 Tampermonkey 提供的,用来在控制台输出日志,就和 console.log 一样,但是我更愿意使用 console 下属的方法,因为足够强大,如果觉得名字有点长,完全可以自己命名一个变量进行指代。就没必要由脚本管理器再提供一个简写方式。不过也可能是这个方法有什么我没有发现的特别之处。

GM_log('要输出的内容')

GM_openInTab

很容易理解,就是在新标签页中打开一个网址:

GM_openInTab('https://www.appinn.com/')

可以加入第 2 个参数,表示是否在后台打开这个标签页,所以第 2 个参数是一个布尔值。

GM_openInTab('https://www.appinn.com/', 'true')

像上面这样书写这个标签,则会在后台打开.

第 2 个参数也可以是一个对象,用来传入一些配置信息,此选项对象在不同脚本管理器下的支持是不相同的,只说两个相对通用的属性:

  • active: 这个标签打开后是否处于激活状态,默认为 true ,这个设置和是否在后台打开的选项是正好相反的。如果在前台打开那么自然打开之后就是激活状态,如果在后台打开则是没有激活的状态。
  • insert: 新标签页是否紧挨着当前标签,默认为 true,如果设置为 false 一般浏览器会将这个标签放在最后一个。

然后选项中有可能还可以设置新打开的标签是否被固定,或者是否在隐私模式下打开。在使用这些选项之前,请先确定脚本管理器对此支持。不支持的结果就是达不到你预期的效果,但是链接还是可以打开的。

GM_download

这个方法用来生成一个下载,如果你对前端有所了解,就会知道这个其实和打开链接是类似的操作,同时也和获取网络资源的方法相类似。(这些类似是说的在原理层面)

最简单的使用方法就是直接给它要下载文件的网址:

GM_download('https://img3.appinn.net/static/wp-content/uploads/appinn190.png')

也可以再给它第 2 个参数来说明这个下载的文件默认保存为什么名字,推荐使用这个方法,因为有些脚本管理器可能不支持省略文件名称:

GM_download('https://img3.appinn.net/static/wp-content/uploads/appinn190.png', 'logo.png')

对于新人了解上面的书写方法已经足够了。如果需要进行更细致的控制,可以只给一个对象参数,对象中的属性如下:

  • url: 要下载的文件地址,这个是必须的。
  • name: 文件的默认保存名称,这个也是必须的。(不是所有脚本管理器都支持省略名称
  • onload: 当下载完成后要执行的函数
  • headers: 下载请求的头信息
  • save As:一个布尔型,是否显示另存为的对话框(Tampermonkey 支持)
  • onerror: 当下载出错时要执行的函数
  • onprogress: 在下载进度发生变化时执行的函数
  • ontimeout: 由于超时导致下载失败时需要执行的函数

GM_notification

让浏览器发出一个通知来提醒用户,现在浏览器基本都支持直接发出一个系统级的通知,就是在右下角弹出那种。

最基本的书写方式:

GM_notification('一些要显示在通知中的文本')

但是这样太简陋了,所以我们还可以给它第 2 个参数作为通知的标题:

GM_notification('一些要显示在通知中的文本', '还有标题就显得很专业')

如果有需要,还可以加入第 3 个参数,放入一个图片地址,它会显示在通知之中。第 4 个参数可以是一个函数,当这个通知被用户点击会执行此函数。这些都是可供选择的,我就不一一演示了。

如果需要更复杂的控制,同样可以传入一个对象作为参数,对象的通用属性如下:

  • text: 要在通知中显示的文字内容(必须)
  • title: 通知的标题
  • image: 要显示在通知中的图片
  • ondone:通知被关闭时要执行的函数(无论是何种原因使通知被关闭,都会触发此函数
  • onclick: 通知被点击时要执行的函数

还有一些其他属性可供选择,但是不同的脚本管理器有不同的设置,就不在这里详细举例了。

Tampermonk 中提供了通知超时的设置,即超过一定时间通知自动关闭。Violentmonkey 则是提供了 remove() 方法来移除通知(但我并未尝试出具体的使用方法)。所以让脚本发出一个通知是容易的,但是想让通知自动关闭却没有一个通行的并且可靠的方法。

GM_setClipboard

将内容写入系统剪切板,就是通过脚本复制。

GM_setClipboard('这些文本会被放入到剪切板之中')

它还可以有第 2 个参数来说明内容的类型,默认值是:text/plain ,就是纯文本。

如果需要设置为其它类型,可以自行查阅 MIME types 的相关信息。但除文本以外的内容复制效果不一定能够得到确切的保证。

GM_setValue

保存一个数据,这会保存在这个脚本自有的储存空间,以供此脚本随时访问,它不受标签页关闭、刷新以及浏览器关闭等操作的影响。借助这样的全局数据,我们可以实现页面间的通讯。此数据可在脚本设置中进行观察。不同脚本间的数据并不互通。我们可以将比如用户对脚本的设置等需要延续性的数据存储到这里。

GM_setValue(‘myAge’, 16)

第 1 个参数是这个数据的名字,第 2 个参数是它的值,这两个参数都是必须的。

GM_getValue

凭数据的名称,获取已保存的数据值。

let data = GM_getValue('myAge')

但有一种很容易出现的尴尬情况,就是当我们试图获取这个数据的时候,其实它还没有被储存过,也就是还不存在。因为这种现象太普遍了,所以准备了一个快捷的解决方法,就是给它第 2 个参数作为默认值,像下面这样:

let data = GM_getValue('myAge', 18)

如果我们获取到已经储存的数据,那就使用获取到的值作为结果,如果发现还没有储存这个数据,就使用后面的默认值,这里是 18。

GM_deleteValue

删除一个已储存的数据,只要有这个数据的名字就行了。

GM_deleteValue('myAge')

GM_listValues

当我们存储的数据比较多的时候,就可能记不起来都存储了哪些数据。又或者我只是想判断一下现在有哪些数据已经被存储。就可以使用这个方法,它会返回一个数组,数组中是所有已存储数据的名字。

const dataNameArray = GM_listValues()

GM_addValueChangeListener

添加一个监听器,某个储存的数据发生变化时,就执行对应的操作。第 1 个参数是这个数据的名字,第 2 个参数是要执行的操作(一般是一个函数)。

调用对应的操作时,会向它传入 4 个参数:

  • 这个数据的名称
  • 这个数据以前的值
  • 这个数据改变以后的值
  • 是否是由其他标签页造成的修改
const listenerId = GM_addValueChangeListener('myAge', (name, oldAge, newAge)=>{
    console.log('我以前的年纪是 ', oldAge, ' ,现在的年纪是 ', newAge)
})

这个操作会返回一个编号,用来标识此监听器。

GM_removeValueChangeListener

凭借监听器的编号移除对数据变化的监听。

GM_removeValueChangeListener(listenerId)

GM_getResourceText

获取资源的文本内容,它只有一个参数,就是这个资源的名称。这个资源应该在元数据中以如下形式进行声明:

// @resource logo https://img3.appinn.net/static/wp-content/uploads/appinn190.png

然后我们就可以像下面这样获取:

const text = GM_getResourceText('logo')
console.log(text)

但需要注意,此方法会将资源当作文本内容进行读取,所以适合用来获取一些文本类的信息,比如 Json 格式的文件。上面举例中因为资源是一个图片,所以用此方法,输出的内容会是一片乱码。

GM_getResourceURL

这个方法用来获取资源的 Blob 格式数据地址。可以用来读取各种二进制文件,就比如图片。

const blobUrl = GM_getResourceURL('logo')
const img = new Image()
img.src = blobUrl

GM_registerMenuCommand

这个方法可以注册一个脚本菜单,它只是出现在脚本管理器的弹出列表中,方便用户操作。

GM_registerMenuCommand('这里是显示的名称', ()=>{
	console.log('啊,你点击了菜单~')
})

第 1 个参数是菜单显示的名称,第 2 个参数是当菜单被点击时要执行的动作。

GM_unregisterMenuCommand

用来移除一个脚本菜单,这个操作在不同的脚本管理器下有所不同。

Violentmonkey 下:凭借菜单显示的文字即可删除对应菜单。

GM_unregisterMenuCommand('菜单显示的文字')

Tampermonkey 下: 注册菜单时会返回一个菜单 ID,然后凭借这个 ID 去删除对应的菜单。

const menuID = GM_registerMenuCommand('这里是显示的名称', ()=>{
	console.log('啊,你点击了菜单~')
})

GM_unregisterMenuCommand(menuID)

GM_xmlhttpRequest

创建一个 xmlHttpRequest 请求。如果你不懂,那基本现在也用不上。

它的参数是一个对象,其中包含有大量可选属性。

  • method: 发起请求的方法,可选: GET, HEAD, POST,默认: GET
  • url:请求的目标网址
  • headers:请求的头信息
  • dataPOST 方法下要发送的数据
  • cookie: 需要额外附加的 cookie 信息,这是在页面原有 cookie 信息之外增加的补丁。Tampermonkey 支持此属性
  • binary: 用二进制模式发送数据
  • nocache:不对资源进行缓存,Tampermonkey 支持此属性
  • revalidate:重新验证缓存的资源,如果通过验证则使用缓存,Tampermonkey 支持此属性
  • timeout: 请求的超时时限,单位是毫秒(ms)
  • context: 请求的上下文
  • responseType:请求期望的资源类型,默认为:text,可选值有: textjsonblobarraybufferdocument(此值 Violentmonkey 支持)
  • overrideMimeType: 请求的 MIME type 类型
  • anonymous:匿名模式,设为 true 则不发送任何 cookie 信息
  • fetch:使用 fetch 而不是 xhr 请求,Tampermonkey 支持此属性,且为测试功能
  • username: 用于验证的用户名
  • password:用于验证的密码

下面内容同样放在这个参数对象之中,它们是一些事件的处理方法。

  • onabort: 如果请求被终止,则执行此操作
  • onerror: 如果请求出现错误,则执行此操作
  • onloadstart: 当请求开始加载,则执行此操作
  • onprogress: 当请求的进度发生变化,则执行此操作
  • onreadystatechange: 如果请求的状态发生改变,则执行此操作
  • ontimeout: 当请求超时,则执行此操作
  • onload: 当请求完成,则执行此操作

执行上述事件所对应的处理方法时,会传入如下参数:

  • finalUrl:从请求中返回的重定向地址
  • readyState:请求完成的状态,这是一个数字
  • status:请求的状态,这是一个数字
  • statusText:请求状态的文本
  • responseHeaders: 响应的头部信息
  • response:响应的数据对象
  • responseXML:将响应数据当作 XML 文档读取,Tampermonkey 支持此属性
  • responseText:将响应数据当作纯文本文档读取,Tampermonkey 支持此属性

发出请求会返回一个对象,这个对象有如下属性:

  • abort:这是一个用来终止该请求的函数

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment