简介
Tampermonkey 油猴脚本可以在任意网页上管理和运行指定脚本的脚本管理器。从而实现各种丰富的DIY功能。
使用
-
下载tampermonkey,选择对应的浏览器版本进行下载。
-
下载后安装到浏览器的扩展程序。一般情况是在扩展程序的开发模式中直接拖入即可。但是也有的浏览器无法直接拖入使用,只需要把“tampermonkey_stable.crx”修改为“tampermonkey_stable.rar”,然后解压到当前文件夹,最后让浏览器的扩展程序加载已解压的扩展程序即可使用。
-
可以在tampermonkey的用户脚本选项搜索需要的脚本,也可以自定义脚本。安装脚本后打开网站就可以运行安装的脚本了。
自定义脚本参数
以下配置是以注释的形式显示的,并且注释是不能去掉的。
- @name:脚本名称
- @namespace:脚本的命名空间
- @version:脚本的版本,用于检查更新。但需要用户设置更新频率
- @author:脚本的作者
- @description:脚本简短重要的描述
- @homepage、@homepageURL、@website、 @source:在选项页面上用于将脚本名称链接到给定页面的作者主页。 请注意,如果@namespace标记以“ http://”开头,其内容也将用于此
- @icon、@iconURL、@defaulticon:低分率的脚本图标,会在脚本管理列表上显示
- @icon64、@icon64URL:此脚本图标为64x64像素。如果还配置了@icon,那么@icon图像将在选项页面被缩放
- @updateURL:用户脚本的更新URL。注意:需要一个@version标记才能进行更新检查。
- @downloadURL:定义检测到更新时将从中下载脚本的 URL。如果值为 none,则不会执行更新检查
- @supportURL:定义用户可以用来报告问题并获得个人支持的URL
- @include:脚本应该运行的页面, 可以使用正则匹配。 允许多个标签, 请注意 @include 不支持 url hash 参数。用法如下:
// @include http://www.tampermonkey.net/*
// @include http://*
// @include https://*
// @include /^https:\/\/www\.tampermonkey\.net\/.*$/
// @include *
- @match 和 @include 标签含义类似, 表示在匹配的网站上执行此脚本。scheme部分也接受"http*://"。
// @match *://*/*
// @match https://*/*
// @match http://*/foo*
// @match https://*.tampermonkey.net/foo*bar
- @exclude 排除 URL,即使它们包含在 @include 或 @match 中。同样允许多个标签。
- @require 指向一个脚本文件,会在脚本运行前加载并执行 我们可以使用这个配置引入 jQuery, 不过要注意:通过 @require 加载的脚本及其“use strict”语句可能会影响用户脚本的 strict 模式!
- @resource:预加载一些资源,HTML、JSON,脚本可以通过 gm_getresourceurl 和 gm_getresourcetext 访问资源。
// @resource icon1 http://www.tampermonkey.net/favicon.ico
// @resource icon2 /images/icon.png
- @connect:此标记定义域(无顶级域),包括允许GM_xmlhttpRequest检索的子域。
// @connect <value>
value 可以是以下值:
* 域名可以是类似:tampermokey.net(这种可以允许子域名)
* 子域名可以类似:a.tampermokey.net
* self:可以将脚本当前运行的域列入白名单
* localhost:访问本机地址
* IP地址,类似:1.2.3.4
// @connect tmnk.net
// @connect www.tampermonkey.net
// @connect self
// @connect localhost
// @connect 8.8.8.8
// @connect *
- @run-at:定义脚本被注入的时刻。与其他脚本处理程序相反,@run-at定义了脚本想要运行的第一个可能时刻。这意味着可能会发生这样的情况,使用@require标记的脚本可能会在文档已经加载之后执行,因为获取所需的脚本需要很长时间。无论如何,在给定的注入时刻之后发生的所有 DOMNodeInserted 和 DOMContentLoaded 事件都会被缓存,并在注入脚本时交付给脚本。
// 脚本将以尽可能快的速度被注入
// @run-at document-start
// 如果body元素存在,则会注入脚本。
// @run-at document-body
// 将在调度DOMContentLoaded事件时或之后注入脚本。
// @run-at document-end
// 将在调度DOMContentLoaded事件之后注入脚本。如果没有给出@run at标记,这是默认值。
// @run-at document-idle
// 如果在浏览器上下文菜单上单击脚本(仅限基于Chrome的桌面浏览器),则会注入该脚本。
// 注意:如果使用此值,所有@include和@exclude语句都将被忽略,但将来可能会更改。
// @run-at context-menu
- @grant
@grant 被用于设置 GM_*
类型函数的白名单,另外window.close和window.focus必须显式声明。如果使用// @grant none,沙箱将被禁用,脚本将直接在页面上下文中运行。在此模式下,没有GM_ 函数,但GM_info属性仍然可用。
- @noframes:这个标记使脚本在主页上运行,但不在iframes上运行。
应用编程接口
Tampermonkey为了更好的扩展网站,整合数据的需求,提供的一些好用的API。
- unsafeWindow unsafeWindow 对象提供访问页面的 Javascript 函数和变量的权限。此对象不用使用 @grant 获取权限。
- GM_addStyle(css) GM_addStyle 函数可以向 DOM 中直接添加 CSS 样式,参数是字符串样式。
// @grant GM_addStyle
GM_addStyle(`body{color:red},p{color:blue}`)
GM_addStyle(`.download_btn {}`);
- 数据存储问题
// 向 storage 中存储一个键值对,键为key,值为value
GM_setValue(key,value)
// 从 storage 中获取 key 对应的值, 如果不存在,将返回默认值null并将其存储在savedTab变量中。
GM_getValue(key, defaultValue)
// 列出 storage 所有的值
GM_listValues()
// 从 storage 中删除 key 的值
GM_deleteValue(key)
- GM_openInTab(url, options), GM_openInTab(url, loadInBackground) 允许用户脚本在浏览器中打开一个新的选项卡并导航到指定的URL。
// @grant GM_openInTab
GM_openInTab('https://www.baidu.com/', {active: true, insert: true, setParent:true})
options参数:
* active:判断是否聚焦到新标签页
* insert:在当前标签后面添加新标签
* setParent:在标签关闭后重新聚焦当前标签
* incognito:在隐私窗口下打开标签
* loadInBackground:该参数与 active 参数的意义相反
-
GM_addValueChangeListener(name, function(name, old_value, new_value, remote) {}) 在 Storage 里添加一个改变事件的监听,并返回监听 id。name 是被观察的变量。回调函数中的 remote 变量是显示此值是从另一个标签页的实例修改的(true)还是在此脚本实例中修改的(false)。因此,不同浏览器标签页下的脚本可以使用此功能相互通信。可以使用此 API 实现不同浏览器 Tab 的相互通讯,此函数返回一个 listener_id 用于移除监听事件。
-
GM_removeValueChangeListener(listener_id) 通过 listener_id 移除监听事件。
-
GM_log(message) 向终端打印日志
-
GM_getResourceText(name) 允许用户脚本通过@resource访问用户脚本中包含的资源(如JavaScript或CSS文件)的文本
-
GM_getResourceURL(name) 允许用户脚本通过脚本头部的@resource标记访问用户脚本中包含的资源(如CSS或图像文件)的URL。
-
GM_registerMenuCommand(name, fn, accessKey)
注册一个菜单,该菜单将显示在运行此脚本的页面的 Tampermonkey 菜单上,并返回菜单命令ID。
- GM_unregisterMenuCommand(menuCmdId)
用给定的菜单命令ID注销先前由 GM_registerMenuCommand 注册的菜单命令。
- GM_xmlhttpRequest(details) 发送 xmlHttpRequest 请求,GM_xmlhttpRequest 返回具有abort(取消该请求的函数)方法的对象,details参数不支持同步请求。
GM_xmlhttpRequest({
method: "GET",
url: "https://example.com/",
headers: { "Content-Type": "application/json" },
onload: function(response) {
console.log(response.responseText);
}
});
details参数:
method 请求方法:GET, HEAD, POST
url 请求网址
headers 请求头
data POST需要发送的内容
cookie 请求所需的Cookie
binary 发送的二进制内容
nocache 不缓存资源
revalidate 重新验证可能缓存的内容
timeout 超时时间 毫秒
context 将添加到响应对象的属性
responseType 响应类型:arraybuffer, blob, json
overrideMimeType MIME 类型的请求
anonymous 匿名发送 不发送Cookie
fetch (beta) 使用 fetch 方法 而不是会用 xhr request
username 用于身份验证的用户名
password 用于身份验证的密码
onabort 请求中止时要执行的回调
onerror 如果请求以错误结束则执行的回调
onloadstart 请求开始加载时要执行的回调
onprogress 请求取得一定进展时要执行的回调
onreadystatechange 请求就绪状态更改时要执行的回调
ontimeout 请求超时失败时要执行的回调
onload 如果请求已加载,将执行的回调。
response具有以下属性:
finalUrl - 经过重定向以后的最终网址,数据从该网址加载出来
readyState - 就绪状态
status - 请求状态码
statusText - 请求状态文本
responseHeaders - 响应头
response - 响应
responseXML - 响应的XML格式
responseText - 响应字符串
- GMdownload(details)、GMdownload(url,name) 下载资源到本地磁盘。
details 的属性:
url:资源的 url
name:文件名,出于安全原因,文件的扩展名必须在页面的的白名单里
headers:如 GM_xmlhttpRequest 一样设置请求头部
saveAs:boolean 值,显示一个保存的弹窗
onerror:下载以失败结束执行的回调函数
onload 现在完成后执行的回调函数
onprogress 下载过程中变化的回调函数
ontimeout 下载超时执行的回调函数
- GM_notification(details,ondone)、GM_notification(text,title,image,onclick) 显示一个 H5 的桌面通知,或者高亮当前 tab。
details 的属性:
text:通知的问题 如果高亮就 就不需要
title:通知的标题
image:图片
highlight:一个 boolean 标志,是否高亮 tab
silent - 一个 boolean 是否播放音乐
timeout:通知显示的时间 0 表示 一直显示
ondone:通知被关闭时 无论是被点击还是超时 执行的函数
onclick:点击通知触发的函数
- GM_setClipboard(data,info) 复制数据到粘贴板,参数 info 可以是对象如 {type: 'text', mimetype: 'text/plain'},或者是一个字符串 text、html。
示例
// ==UserScript==
// @name 下载文档图片
// @namespace http://tampermonkey.net/
// @version 0.1
// @description 下载文档图片
// @author wzl
// @match https://www.xxx.com/*
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant GM_addStyle
// @grant GM_xmlhttpRequest
// @grant GM_download
// @require http://libs.baidu.com/jquery/2.0.0/jquery.min.js
// ==/UserScript==
(function () {
"use strict";
/* globals jQuery, $, waitForKeyElements */
$(function () {
let css = `
.download_btn {
position: fixed;
right: 10px;
top: 10px;
padding: 0 10px;
border-radius: 4px;
line-height: 30px;
background: red;
color: #fff;
cursor: pointer;
z-index: 999999;
}
`;
// GM_addStyle 修改样式
GM_addStyle(css);
let $body = $("body");
$body.append('<div class="download_btn">下载</div>');
// 获取url的参数
function getQueryletiable(url, letiable) {
let query = new URL(url).search.substring(1);
query = decodeURI(query);
let lets = query.split("&");
for (let i = 0; i < lets.length; i++) {
let pair = lets[i].split("=");
if (pair[0] === letiable) {
return pair[1];
}
}
return false;
}
let namePrefix = "下载的文件名";
//处理jsonp返回的数据
function toSave(data) {
if (Object.keys(data.data).length > 0) {
// GM_download 下载文件
GM_download("文件地址", `${namePrefix}.png`);
} else {
alert("下载完毕");
}
}
function toGetImgs(_url) {
// GM_xmlhttpRequest 请求数据
GM_xmlhttpRequest({
method: "GET",
url: _url,
onload: (res) => {
if (res.status === 200) {
let callbackName = getQueryletiable(_url, "callback");
// 如果是jsonp,处理获取到的数据
let fn = res.response.replace(callbackName, "toSave");
eval(fn);
}
},
});
}
function replaceParamVal(url, paramName, replaceWith) {
let oUrl = url;
let re = eval("/(" + paramName + "=)([^&]*)/gi");
let nUrl = oUrl.replace(re, paramName + "=" + replaceWith);
return nUrl;
}
function toDownload() {
let ms = new Date().getTime();
// 替换路由参数
_url = replaceParamVal(_url, "page", 1);
toGetImgs(_url);
}
let _url = "请求数据的地址";
$(".download_btn").click(function () {
toDownload();
});
});
})();