Skip to content

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.

ts
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.

ts
config: Record<string, unknown>

Example:

js
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.

ts
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;
}>
OptionTypeDefaultDescription
urlstring-Request URL.
methodstringGETHTTP method.
dataany-Request data. For GET and HEAD, it is serialized into the query string. For other methods, it is written to the request body.
headersRecord<string, string>{}Request headers.
timeoutnumber-Timeout in milliseconds. It takes effect only when greater than 0.
dataType'json' | 'text' | 'html' | 'arrayBuffer'jsonResponse parsing mode.
contentTypestringapplication/x-www-form-urlencoded; charset=UTF-8Request body Content-Type.
processDatabooleantrueWhether to automatically serialize data. Set to false to pass data directly as the request body.

Return value:

FieldTypeDescription
okbooleantrue for HTTP 2xx responses; false for parsing errors, HTTP errors, timeout, abort, or network errors.
statusnumberHTTP status code. 0 indicates timeout, abort, or network-level failure.
statusTextstringHTTP status text, or timeout, abort, or error for non-HTTP failures.
dataanyParsed response data, present when parsing succeeds.
errorstringError message, present for parsing failures or non-HTTP failures.
timeoutbooleantrue when the request was aborted by the configured timeout.

Examples:

js
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);
}
js
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:

ParameterTypeDefaultDescription
sitebooleanfalseWhether to store data by site.
accountbooleanfalseWhether to store data by account.
didbooleanfalseWhether to store data by device.

api.user.put(name, value, site, account, did)

Save the specified key-value pair.

ts
put(
  name: string,
  value: string,
  site?: boolean,
  account?: boolean,
  did?: boolean
): Promise<{ status: boolean }>

Example:

js
await api.user.put('token', 'abc123');

api.user.get(name, site, account, did)

Read the specified key-value pair.

ts
get(
  name: string,
  site?: boolean,
  account?: boolean,
  did?: boolean
): Promise<{ value: string | null, status: boolean }>

Example:

js
const ret = await api.user.get('token');
console.log(ret.value);

api.user.remove(name, site, account, did)

Delete the specified key-value pair.

ts
remove(
  name: string,
  site?: boolean,
  account?: boolean,
  did?: boolean
): Promise<{ status: boolean }>

Example:

js
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.

ts
incr(
  name: string,
  step?: number,
  site?: boolean,
  account?: boolean,
  did?: boolean
): Promise<{ status: boolean, value: number | string }>

Example:

js
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.

ts
decr(
  name: string,
  step?: number,
  site?: boolean,
  account?: boolean,
  did?: boolean
): Promise<{ status: boolean, value: number | string }>

Example:

js
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.

ts
startsWith(
  prefix: string,
  site?: boolean,
  account?: boolean,
  did?: boolean
): Promise<Array<{ name: string, value: string }>>

Example:

js
const items = await api.user.startsWith('cache:');

api.user.countAll(name, site, account)

Count records with the specified key name.

ts
countAll(
  name: string,
  site?: boolean,
  account?: boolean
): Promise<{ value: number, status: boolean }>

Example:

js
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.

ts
sumAll(
  name: string,
  site?: boolean,
  account?: boolean
): Promise<{ value: number, status: boolean }>

Example:

js
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:

PatternDescription
.button.primaryCSS selector.
xpath://div[@id="app"]XPath selector.
.dialog:pReturn the parent element of the matched element.
.dialog:p2Return the parent two levels above the matched element.
.header:bottomUse the bottom boundary of the target element in overlay boundary methods.
.sidebar:rightUse 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.

ts
createMutationObserver(
  ele: Element,
  bindStr: string,
  childList: boolean,
  subtree: boolean,
  attributes: boolean,
  characterData: boolean,
  fn: (mutations: MutationRecord[]) => void
): MutationObserver

Example:

js
api.dom.createMutationObserver(
  document.body,
  '__bodyObserver__',
  true,
  true,
  false,
  false,
  (mutations) => console.log(mutations)
);

api.dom.querySelector(doc, cssOrXPathSelector)

Query the first matching element.

ts
querySelector(doc: Document, cssOrXPathSelector: string): HTMLElement | null

Example:

js
const el = api.dom.querySelector(document, 'xpath://button[contains(.,"Submit")]');

api.dom.querySelectorAll(doc, cssOrXPathSelector)

Query all matching elements.

ts
querySelectorAll(doc: Document, cssOrXPathSelector: string): HTMLElement[]

Example:

js
const buttons = api.dom.querySelectorAll(document, 'button.primary');

api.dom.isVisible(ele)

Determine whether the element is in a visible intersection area.

ts
isVisible(ele: HTMLElement): Promise<boolean>

Example:

js
if (await api.dom.isVisible(el)) {
  console.log('visible');
}

api.dom.getVisibleRect(ele)

Get the current visible rectangle of the element.

ts
getVisibleRect(ele: HTMLElement): Promise<DOMRectReadOnly>

Example:

js
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.

ts
getConnectListeners(): Array<{
  querySelector: string;
  callback: (isConnected: boolean) => void;
  isConnected?: boolean;
}>

Example:

js
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.

ts
addConnectListener(
  cssOrXPathSelector: string,
  callback: (isConnected: boolean) => void
): void

Example:

js
api.dom.addConnectListener('.dialog', (isConnected) => {
  console.log('dialog:', isConnected);
});

api.dom.removeConnectListener(cssOrXPathSelectors)

Remove connection listeners for the specified selectors.

ts
removeConnectListener(cssOrXPathSelectors: string[]): void

Example:

js
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).

ts
addResizeListener(
  cssOrXPathSelector: string,
  bindWindowStr: string,
  callback: (rect: DOMRect) => void,
  createObserver?: boolean,
  delayTime?: number
): ResizeObserver | (() => void)

Example:

js
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.

ts
createOverlayBy(
  cssOrXPathSelector: string,
  bindWindowStr: string,
  createObserver?: boolean,
  delayTime?: number,
  fn?: (rect: DOMRectReadOnly) => void
): HTMLElement

Example:

js
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.

ts
createOverlayByBorder(
  bindWindowStr: string,
  top: string | number,
  right: string | number,
  bottom: string | number,
  left: string | number,
  createObserver?: boolean,
  delayTime?: number
): HTMLElement

Example:

js
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.

ts
wait(
  fn: () => boolean,
  timeoutMs: number,
  intervalMs?: number
): Promise<void>

After timeout, it throws Error("Timeout: function did not return true in time.").

Example:

js
await api.utils.wait(
  () => !!api.dom.querySelector(document, '.ready'),
  10000,
  200
);

api.utils.runScript(code, callback)

Execute JavaScript code in the current page.

ts
runScript(
  code: string,
  callback?: (result: any, error: Error) => void
): Promise<any>

Example:

js
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.

ts
header(
  headerName: string,
  isRequestHeader: boolean
): Promise<string | string[] | undefined>
ParameterTypeDescription
headerNamestringRequest or response header name. It is converted to lowercase when read.
isRequestHeaderbooleantrue 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:

js
const cookie = await api.header('cookie', true);
const setCookie = await api.header('set-cookie', false);

Sa2web 1.0.0