脚本 API 附录
目标
说明站点页面脚本和接口拦截脚本可以使用的 window.api 能力,包括配置读取、HTTP 请求、用户数据、DOM 工具、通用工具、请求头和响应头读取。
页面脚本和普通接口拦截脚本可以使用 window.api。SSE 脚本只保证传入 data,通常不依赖 window.api。
interface Window {
api: {
user: UserApi;
http: HttpApi;
config: Record<string, unknown>;
dom: DomApi;
utils: UtilsApi;
header(headerName: string, isRequestHeader: boolean): Promise<string | string[] | undefined>;
};
}api.config
读取站点脚本环境中的自定义配置。
config: Record<string, unknown>示例:
const apiBase = api.config.apiBase;api.http
api.http 为用户脚本提供 HTTP 请求工具。api.http.ajax 会在浏览器主进程中执行实际请求,因此不受页面 CORS 策略限制。
api.http.ajax(options)
发送 HTTP 请求。
ajax(options: {
url: string;
method?: string;
data?: any;
headers?: Record<string, string>;
timeout?: number;
dataType?: 'json' | 'text' | 'html' | 'arrayBuffer';
contentType?: string;
processData?: boolean;
}): Promise<{
ok: boolean;
status: number;
statusText: string;
data?: any;
error?: string;
timeout?: boolean;
}>| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
url | string | - | 请求 URL。 |
method | string | GET | HTTP 方法。 |
data | any | - | 请求数据。GET 和 HEAD 请求会序列化到查询字符串;其它方法会写入请求体。 |
headers | Record<string, string> | {} | 请求头。 |
timeout | number | - | 超时时间,单位毫秒。仅大于 0 时生效。 |
dataType | 'json' | 'text' | 'html' | 'arrayBuffer' | json | 响应解析方式。 |
contentType | string | application/x-www-form-urlencoded; charset=UTF-8 | 请求体 Content-Type。 |
processData | boolean | true | 是否自动序列化 data。设为 false 时会把 data 直接作为请求体传入。 |
返回值:
| 字段 | 类型 | 说明 |
|---|---|---|
ok | boolean | HTTP 2xx 响应为 true;解析错误、HTTP 错误、超时、中止或网络错误为 false。 |
status | number | HTTP 状态码。0 表示超时、中止或网络层失败。 |
statusText | string | HTTP 状态文本;非 HTTP 失败时为 timeout、abort 或 error。 |
data | any | 解析成功后的响应数据。 |
error | string | 解析失败或非 HTTP 失败时的错误消息。 |
timeout | boolean | 请求因配置的超时时间被中止时为 true。 |
示例:
const ret = await api.http.ajax({
url: 'https://example.com/api/profile',
method: 'GET',
dataType: 'json',
timeout: 10000
});
if (ret.ok) {
console.log(ret.data);
}const ret = await api.http.ajax({
url: 'https://example.com/api/items',
method: 'POST',
contentType: 'application/json',
data: { name: 'demo' }
});api.user
api.user 用于读写脚本运行过程中的用户关联数据。
通用参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
site | boolean | false | 是否分站点存储。 |
account | boolean | false | 是否分账号存储。 |
did | boolean | false | 是否分设备存储。 |
api.user.put(name, value, site, account, did)
保存指定键值。
put(
name: string,
value: string,
site?: boolean,
account?: boolean,
did?: boolean
): Promise<{ status: boolean }>示例:
await api.user.put('token', 'abc123');api.user.get(name, site, account, did)
读取指定键值。
get(
name: string,
site?: boolean,
account?: boolean,
did?: boolean
): Promise<{ value: string | null, status: boolean }>示例:
const ret = await api.user.get('token');
console.log(ret.value);api.user.remove(name, site, account, did)
删除指定键值。
remove(
name: string,
site?: boolean,
account?: boolean,
did?: boolean
): Promise<{ status: boolean }>示例:
await api.user.remove('token');api.user.incr(name, step, site, account, did)
按步长增加指定键的数值。键不存在时会创建该键,值为 step。
incr(
name: string,
step?: number,
site?: boolean,
account?: boolean,
did?: boolean
): Promise<{ status: boolean, value: number | string }>示例:
const ret = await api.user.incr('count', 1);
console.log(ret.value);api.user.decr(name, step, site, account, did)
按步长减少指定键的数值。键不存在时会创建该键,值为 step * -1。
decr(
name: string,
step?: number,
site?: boolean,
account?: boolean,
did?: boolean
): Promise<{ status: boolean, value: number | string }>示例:
const ret = await api.user.decr('count', 1);
console.log(ret.value);api.user.startsWith(prefix, site, account, did)
查找所有键名以指定前缀开头的数据。
startsWith(
prefix: string,
site?: boolean,
account?: boolean,
did?: boolean
): Promise<Array<{ name: string, value: string }>>示例:
const items = await api.user.startsWith('cache:');api.user.countAll(name, site, account)
统计指定键名的记录数量。
countAll(
name: string,
site?: boolean,
account?: boolean
): Promise<{ value: number, status: boolean }>示例:
const ret = await api.user.countAll('token');
console.log(ret.value);api.user.sumAll(name, site, account)
统计指定键名对应值的数值总和。
sumAll(
name: string,
site?: boolean,
account?: boolean
): Promise<{ value: number, status: boolean }>示例:
const ret = await api.user.sumAll('score');
console.log(ret.value);api.dom
api.dom 提供 DOM 查询、可见性判断、连接监听、尺寸监听和覆盖层创建能力。
选择器支持:
| 写法 | 说明 |
|---|---|
.button.primary | CSS 选择器。 |
xpath://div[@id="app"] | XPath 选择器。 |
.dialog:p | 返回匹配元素的父元素。 |
.dialog:p2 | 返回匹配元素向上两级的父元素。 |
.header:bottom | 覆盖层边界方法中取目标元素下边界。 |
.sidebar:right | 覆盖层边界方法中取目标元素右边界。 |
api.dom.createMutationObserver(ele, bindStr, childList, subtree, attributes, characterData, fn)
创建并缓存 MutationObserver。如果 ele[bindStr] 已存在,会直接返回已有 observer。
createMutationObserver(
ele: Element,
bindStr: string,
childList: boolean,
subtree: boolean,
attributes: boolean,
characterData: boolean,
fn: (mutations: MutationRecord[]) => void
): MutationObserver示例:
api.dom.createMutationObserver(
document.body,
'__bodyObserver__',
true,
true,
false,
false,
(mutations) => console.log(mutations)
);api.dom.querySelector(doc, cssOrXPathSelector)
查询第一个匹配元素。
querySelector(doc: Document, cssOrXPathSelector: string): HTMLElement | null示例:
const el = api.dom.querySelector(document, 'xpath://button[contains(.,"提交")]');api.dom.querySelectorAll(doc, cssOrXPathSelector)
查询所有匹配元素。
querySelectorAll(doc: Document, cssOrXPathSelector: string): HTMLElement[]示例:
const buttons = api.dom.querySelectorAll(document, 'button.primary');api.dom.isVisible(ele)
判断元素是否处于可见交叉区域。
isVisible(ele: HTMLElement): Promise<boolean>示例:
if (await api.dom.isVisible(el)) {
console.log('visible');
}api.dom.getVisibleRect(ele)
获取元素当前可见区域矩形。
getVisibleRect(ele: HTMLElement): Promise<DOMRectReadOnly>示例:
const rect = await api.dom.getVisibleRect(el);
console.log(rect.left, rect.top, rect.width, rect.height);api.dom.getConnectListeners()
获取当前连接监听器列表。
getConnectListeners(): Array<{
querySelector: string;
callback: (isConnected: boolean) => void;
isConnected?: boolean;
}>示例:
api.dom.addConnectListener('.modal', () => {});
console.log(api.dom.getConnectListeners());api.dom.addConnectListener(cssOrXPathSelector, callback)
监听目标元素是否出现在文档中或从文档中消失。
addConnectListener(
cssOrXPathSelector: string,
callback: (isConnected: boolean) => void
): void示例:
api.dom.addConnectListener('.dialog', (isConnected) => {
console.log('dialog:', isConnected);
});api.dom.removeConnectListener(cssOrXPathSelectors)
移除指定选择器对应的连接监听器。
removeConnectListener(cssOrXPathSelectors: string[]): void示例:
api.dom.removeConnectListener(['.dialog', '.toast']);api.dom.addResizeListener(cssOrXPathSelector, bindWindowStr, callback, createObserver, delayTime)
监听目标元素尺寸和位置变化。元素不存在时,回调会收到 new DOMRect(0, 0, 0, 0)。
addResizeListener(
cssOrXPathSelector: string,
bindWindowStr: string,
callback: (rect: DOMRect) => void,
createObserver?: boolean,
delayTime?: number
): ResizeObserver | (() => void)示例:
api.dom.addResizeListener('.target', '__targetResize__', (rect) => {
console.log(rect.width, rect.height);
});api.dom.createOverlayBy(cssOrXPathSelector, bindWindowStr, createObserver, delayTime, fn)
创建一个跟随目标元素可见区域的固定定位覆盖层。
createOverlayBy(
cssOrXPathSelector: string,
bindWindowStr: string,
createObserver?: boolean,
delayTime?: number,
fn?: (rect: DOMRectReadOnly) => void
): HTMLElement示例:
const overlay = api.dom.createOverlayBy('.target', '__overlay__');
overlay.style.border = '2px solid #f00';
overlay.style.pointerEvents = 'none';
overlay.style.zIndex = '999999';api.dom.createOverlayByBorder(bindWindowStr, top, right, bottom, left, createObserver, delayTime)
通过四条边创建固定定位覆盖层。每条边可以是数字像素值,也可以是选择器。选择器边界可配合 :top、:right、:bottom、:left 指定使用哪条边。
createOverlayByBorder(
bindWindowStr: string,
top: string | number,
right: string | number,
bottom: string | number,
left: string | number,
createObserver?: boolean,
delayTime?: number
): HTMLElement示例:
const panel = api.dom.createOverlayByBorder(
'__centerPanel__',
'header:bottom',
20,
'footer:top',
'.sidebar:right'
);
panel.style.background = 'rgba(0,0,0,.08)';api.utils
api.utils.wait(fn, timeoutMs, intervalMs)
轮询等待条件函数返回真值。
wait(
fn: () => boolean,
timeoutMs: number,
intervalMs?: number
): Promise<void>超时后会抛出 Error("Timeout: function did not return true in time.")。
示例:
await api.utils.wait(
() => !!api.dom.querySelector(document, '.ready'),
10000,
200
);api.utils.runScript(code, callback)
在当前页面执行 JavaScript 代码。
runScript(
code: string,
callback?: (result: any, error: Error) => void
): Promise<any>示例:
const title = await api.utils.runScript('document.title');
console.log(title);api.header(headerName, isRequestHeader)
读取远程浏览器记录的请求头或响应头。
header(
headerName: string,
isRequestHeader: boolean
): Promise<string | string[] | undefined>| 参数 | 类型 | 说明 |
|---|---|---|
headerName | string | 请求头或响应头名称,读取时会转成小写。 |
isRequestHeader | boolean | true 读取请求头,false 读取响应头。 |
注意:
- 只有在站点配置中添加过的请求头或响应头才会被记录。
- 请求头来自远程浏览器发送请求时的 header。
- 响应头来自远程浏览器收到响应时的 header。
- 响应头可能返回字符串数组。
示例:
const cookie = await api.header('cookie', true);
const setCookie = await api.header('set-cookie', false);