Script API Appendix
Goal
Describe the window.api capabilities available to site page scripts and API interception scripts, including configuration reads, HTTP requests, user data, DOM tools, general utilities, and request/response header reads.
Page scripts and normal API interception scripts can use window.api. SSE scripts only guarantee that data is passed in and usually do not depend on 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
Read custom configuration from the site script environment.
config: Record<string, unknown>Example:
const apiBase = api.config.apiBase;api.http
api.http provides HTTP helpers for user scripts. api.http.ajax runs the actual request in the browser main process, so it is not restricted by the page's CORS policy.
api.http.ajax(options)
Send an HTTP request.
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;
}>| Option | Type | Default | Description |
|---|---|---|---|
url | string | - | Request URL. |
method | string | GET | HTTP method. |
data | any | - | Request data. For GET and HEAD, it is serialized into the query string. For other methods, it is written to the request body. |
headers | Record<string, string> | {} | Request headers. |
timeout | number | - | Timeout in milliseconds. It takes effect only when greater than 0. |
dataType | 'json' | 'text' | 'html' | 'arrayBuffer' | json | Response parsing mode. |
contentType | string | application/x-www-form-urlencoded; charset=UTF-8 | Request body Content-Type. |
processData | boolean | true | Whether to automatically serialize data. Set to false to pass data directly as the request body. |
Return value:
| Field | Type | Description |
|---|---|---|
ok | boolean | true for HTTP 2xx responses; false for parsing errors, HTTP errors, timeout, abort, or network errors. |
status | number | HTTP status code. 0 indicates timeout, abort, or network-level failure. |
statusText | string | HTTP status text, or timeout, abort, or error for non-HTTP failures. |
data | any | Parsed response data, present when parsing succeeds. |
error | string | Error message, present for parsing failures or non-HTTP failures. |
timeout | boolean | true when the request was aborted by the configured timeout. |
Examples:
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 reads and writes user-related data during script execution.
Common parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
site | boolean | false | Whether to store data by site. |
account | boolean | false | Whether to store data by account. |
did | boolean | false | Whether to store data by device. |
api.user.put(name, value, site, account, did)
Save the specified key-value pair.
put(
name: string,
value: string,
site?: boolean,
account?: boolean,
did?: boolean
): Promise<{ status: boolean }>Example:
await api.user.put('token', 'abc123');api.user.get(name, site, account, did)
Read the specified key-value pair.
get(
name: string,
site?: boolean,
account?: boolean,
did?: boolean
): Promise<{ value: string | null, status: boolean }>Example:
const ret = await api.user.get('token');
console.log(ret.value);api.user.remove(name, site, account, did)
Delete the specified key-value pair.
remove(
name: string,
site?: boolean,
account?: boolean,
did?: boolean
): Promise<{ status: boolean }>Example:
await api.user.remove('token');api.user.incr(name, step, site, account, did)
Increase the numeric value of the specified key by step. If the key does not exist, it is created with the value step.
incr(
name: string,
step?: number,
site?: boolean,
account?: boolean,
did?: boolean
): Promise<{ status: boolean, value: number | string }>Example:
const ret = await api.user.incr('count', 1);
console.log(ret.value);api.user.decr(name, step, site, account, did)
Decrease the numeric value of the specified key by step. If the key does not exist, it is created with the value step * -1.
decr(
name: string,
step?: number,
site?: boolean,
account?: boolean,
did?: boolean
): Promise<{ status: boolean, value: number | string }>Example:
const ret = await api.user.decr('count', 1);
console.log(ret.value);api.user.startsWith(prefix, site, account, did)
Find all data whose key name starts with the specified prefix.
startsWith(
prefix: string,
site?: boolean,
account?: boolean,
did?: boolean
): Promise<Array<{ name: string, value: string }>>Example:
const items = await api.user.startsWith('cache:');api.user.countAll(name, site, account)
Count records with the specified key name.
countAll(
name: string,
site?: boolean,
account?: boolean
): Promise<{ value: number, status: boolean }>Example:
const ret = await api.user.countAll('token');
console.log(ret.value);api.user.sumAll(name, site, account)
Calculate the numeric sum of values for the specified key name.
sumAll(
name: string,
site?: boolean,
account?: boolean
): Promise<{ value: number, status: boolean }>Example:
const ret = await api.user.sumAll('score');
console.log(ret.value);api.dom
api.dom provides DOM queries, visibility checks, connection listeners, resize listeners, and overlay creation.
Selector support:
| Pattern | Description |
|---|---|
.button.primary | CSS selector. |
xpath://div[@id="app"] | XPath selector. |
.dialog:p | Return the parent element of the matched element. |
.dialog:p2 | Return the parent two levels above the matched element. |
.header:bottom | Use the bottom boundary of the target element in overlay boundary methods. |
.sidebar:right | Use the right boundary of the target element in overlay boundary methods. |
api.dom.createMutationObserver(ele, bindStr, childList, subtree, attributes, characterData, fn)
Create and cache a MutationObserver. If ele[bindStr] already exists, the existing observer is returned directly.
createMutationObserver(
ele: Element,
bindStr: string,
childList: boolean,
subtree: boolean,
attributes: boolean,
characterData: boolean,
fn: (mutations: MutationRecord[]) => void
): MutationObserverExample:
api.dom.createMutationObserver(
document.body,
'__bodyObserver__',
true,
true,
false,
false,
(mutations) => console.log(mutations)
);api.dom.querySelector(doc, cssOrXPathSelector)
Query the first matching element.
querySelector(doc: Document, cssOrXPathSelector: string): HTMLElement | nullExample:
const el = api.dom.querySelector(document, 'xpath://button[contains(.,"Submit")]');api.dom.querySelectorAll(doc, cssOrXPathSelector)
Query all matching elements.
querySelectorAll(doc: Document, cssOrXPathSelector: string): HTMLElement[]Example:
const buttons = api.dom.querySelectorAll(document, 'button.primary');api.dom.isVisible(ele)
Determine whether the element is in a visible intersection area.
isVisible(ele: HTMLElement): Promise<boolean>Example:
if (await api.dom.isVisible(el)) {
console.log('visible');
}api.dom.getVisibleRect(ele)
Get the current visible rectangle of the element.
getVisibleRect(ele: HTMLElement): Promise<DOMRectReadOnly>Example:
const rect = await api.dom.getVisibleRect(el);
console.log(rect.left, rect.top, rect.width, rect.height);api.dom.getConnectListeners()
Get the current connection listener list.
getConnectListeners(): Array<{
querySelector: string;
callback: (isConnected: boolean) => void;
isConnected?: boolean;
}>Example:
api.dom.addConnectListener('.modal', () => {});
console.log(api.dom.getConnectListeners());api.dom.addConnectListener(cssOrXPathSelector, callback)
Listen for whether the target element appears in or disappears from the document.
addConnectListener(
cssOrXPathSelector: string,
callback: (isConnected: boolean) => void
): voidExample:
api.dom.addConnectListener('.dialog', (isConnected) => {
console.log('dialog:', isConnected);
});api.dom.removeConnectListener(cssOrXPathSelectors)
Remove connection listeners for the specified selectors.
removeConnectListener(cssOrXPathSelectors: string[]): voidExample:
api.dom.removeConnectListener(['.dialog', '.toast']);api.dom.addResizeListener(cssOrXPathSelector, bindWindowStr, callback, createObserver, delayTime)
Listen for size and position changes of the target element. If the element does not exist, the callback receives new DOMRect(0, 0, 0, 0).
addResizeListener(
cssOrXPathSelector: string,
bindWindowStr: string,
callback: (rect: DOMRect) => void,
createObserver?: boolean,
delayTime?: number
): ResizeObserver | (() => void)Example:
api.dom.addResizeListener('.target', '__targetResize__', (rect) => {
console.log(rect.width, rect.height);
});api.dom.createOverlayBy(cssOrXPathSelector, bindWindowStr, createObserver, delayTime, fn)
Create a fixed-position overlay that follows the visible area of the target element.
createOverlayBy(
cssOrXPathSelector: string,
bindWindowStr: string,
createObserver?: boolean,
delayTime?: number,
fn?: (rect: DOMRectReadOnly) => void
): HTMLElementExample:
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)
Create a fixed-position overlay from four edges. Each edge can be a numeric pixel value or a selector. Selector edges can use :top, :right, :bottom, and :left to choose the edge.
createOverlayByBorder(
bindWindowStr: string,
top: string | number,
right: string | number,
bottom: string | number,
left: string | number,
createObserver?: boolean,
delayTime?: number
): HTMLElementExample:
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)
Poll until the condition function returns a truthy value.
wait(
fn: () => boolean,
timeoutMs: number,
intervalMs?: number
): Promise<void>After timeout, it throws Error("Timeout: function did not return true in time.").
Example:
await api.utils.wait(
() => !!api.dom.querySelector(document, '.ready'),
10000,
200
);api.utils.runScript(code, callback)
Execute JavaScript code in the current page.
runScript(
code: string,
callback?: (result: any, error: Error) => void
): Promise<any>Example:
const title = await api.utils.runScript('document.title');
console.log(title);api.header(headerName, isRequestHeader)
Read request headers or response headers recorded by the remote browser.
header(
headerName: string,
isRequestHeader: boolean
): Promise<string | string[] | undefined>| Parameter | Type | Description |
|---|---|---|
headerName | string | Request or response header name. It is converted to lowercase when read. |
isRequestHeader | boolean | true reads request headers; false reads response headers. |
Notes:
- Only request headers or response headers added in site configuration are recorded.
- Request headers come from headers sent by the remote browser when it sends requests.
- Response headers come from headers received by the remote browser when it receives responses.
- Response headers may return string arrays.
Example:
const cookie = await api.header('cookie', true);
const setCookie = await api.header('set-cookie', false);