跳到主要内容

JavaScript API 参考

pink-js-engine 提供了一个基于 WebKit 的 JavaScript 运行时环境,支持五种脚本类型:RequestResponseSchedule(定时任务)Generic(通用脚本)Network(网络变化)

所有脚本类型共享一组全局 API,同时每种类型有各自独有的全局变量。脚本执行完毕后必须调用 $done() 来通知引擎。


全局 API

以下 API 在所有脚本类型中均可使用。

$httpClient

发起 HTTP 请求的客户端。支持 getpostputdeleteheadoptionspatch 方法,以及通用的 request 方法。

便捷方法

$httpClient.get(options, callback)
$httpClient.post(options, callback)
$httpClient.put(options, callback)
$httpClient.delete(options, callback)
$httpClient.head(options, callback)
$httpClient.options(options, callback)
$httpClient.patch(options, callback)

通用方法

$httpClient.request(method, options, callback)
  • method — HTTP 方法字符串,如 "GET""POST" 等。

参数

options — 可以是 URL 字符串,或包含以下字段的对象:

字段类型说明
urlstring请求 URL(必填)
headersobject请求头键值对
bodystring | Uint8Array | object请求体。对象会自动序列化为 JSON
binary-modebooleantrue 时,响应体以 Uint8Array 返回
timeoutnumber超时时间(秒)
policystring代理策略名称
auto-redirectboolean是否自动跟随重定向
auto-cookieboolean是否自动管理 Cookie

callbackfunction(error, response, data)

参数类型说明
errorError | undefined请求出错时为 Error 对象,成功时为 undefined
responseobject | undefined包含 status(HTTP 状态码)和 headers(响应头对象)
datastring | Uint8Array | undefined响应体。默认为字符串,binary-mode 时为 Uint8Array

示例

// 简单 GET 请求
$httpClient.get("https://example.com/api", function(error, response, data) {
if (error) {
console.log("请求失败: " + error);
$done();
return;
}
console.log("状态码: " + response.status);
console.log("响应体: " + data);
$done();
});

// 带选项的 POST 请求
$httpClient.post({
url: "https://example.com/api",
headers: { "Content-Type": "application/json" },
body: { key: "value" },
timeout: 10
}, function(error, response, data) {
console.log(data);
$done();
});

// 二进制模式
$httpClient.get({
url: "https://example.com/image.png",
"binary-mode": true
}, function(error, response, data) {
// data 是 Uint8Array
console.log("大小: " + data.length);
$done();
});

// 通用方法
$httpClient.request("PATCH", {
url: "https://example.com/api/resource",
body: "updated"
}, function(error, response, data) {
$done();
});

$persistentStore

持久化键值存储,数据在脚本多次执行之间保留。

方法

$persistentStore.write(data, key)

将字符串值写入存储。

参数类型说明
datastring要存储的值
keystring存储键名

返回值: boolean — 写入成功返回 true,失败返回 false

$persistentStore.read(key)

从存储中读取值。

参数类型说明
keystring存储键名

返回值: string | null — 键对应的值,不存在时返回 null

示例

// 写入
$persistentStore.write("hello", "greeting");

// 读取
const value = $persistentStore.read("greeting");
console.log(value); // "hello"

// 检查是否存在
if ($persistentStore.read("counter") === null) {
$persistentStore.write("0", "counter");
}

$notification

发送系统通知。

方法

$notification.post(title, subtitle, body, options)
参数类型说明
titlestring通知标题
subtitlestring通知副标题
bodystring通知正文
optionsobject可选,附加选项

示例

$notification.post("脚本完成", "子标题", "任务已成功执行");

$notification.post("警告", "", "检测到异常流量", { url: "https://example.com" });

$utils

工具函数集合。

方法

$utils.geoip(ip)

查询 IP 地址的地理位置国家代码。

参数类型说明
ipstringIP 地址

返回值: string | null — ISO 3166-1 国家代码(如 "US""CN"),查询失败返回 null

$utils.ipasn(ip)

查询 IP 地址的自治系统编号(ASN)。

参数类型说明
ipstringIP 地址

返回值: number | null — ASN 编号,查询失败返回 null

$utils.ipaso(ip)

查询 IP 地址的自治系统组织名称(ASO)。

参数类型说明
ipstringIP 地址

返回值: string | null — 组织名称,查询失败返回 null

$utils.ungzip(data)

解压 gzip 数据。

参数类型说明
dataUint8Arraygzip 压缩的数据

返回值: Uint8Array | null — 解压后的数据,失败返回 null

示例

const country = $utils.geoip("8.8.8.8");
console.log(country); // "US"

const asn = $utils.ipasn("1.1.1.1");
console.log(asn); // 13335

const aso = $utils.ipaso("1.1.1.1");
console.log(aso); // "Cloudflare, Inc."

// 解压 gzip 数据
const decompressed = $utils.ungzip(compressedData);

$environment

系统环境信息(只读)。

属性类型说明
systemstring系统标识,固定为 "iOS"
languagestring系统语言

示例

console.log($environment.system);   // "iOS"
console.log($environment.language); // "zh-Hans"

$script

当前脚本的元数据(只读)。

属性类型说明
namestring脚本名称
startTimenumber脚本开始执行的 Unix 时间戳(秒)
typestring | undefined脚本类型:"request""response""cron"undefined

示例

console.log($script.name);      // "my-script"
console.log($script.startTime); // 1700000000.123
console.log($script.type); // "request"

$network

当前设备网络信息(只读)。

$network = {
"cellular-data": {
carrier: string, // 运营商名称
radio: string // 无线电技术(如 "LTE"、"5G")
},
wifi: {
ssid: string, // Wi-Fi 网络名称
bssid: string // Wi-Fi BSSID
},
v4: {
primaryAddress: string, // IPv4 地址
primaryRouter: string, // 网关地址
primaryInterface: string // 网络接口名称
},
v6: {
primaryAddress: string, // IPv6 地址
primaryInterface: string // 网络接口名称
},
dns: string[] // DNS 服务器列表
}

示例

console.log($network.wifi.ssid);
console.log($network.v4.primaryAddress);
console.log($network.dns);

Egern

Egern 应用信息(只读)。

属性类型说明
versionstringEgern 版本号
argumentsobject脚本配置的参数键值对

示例

console.log(Egern.version);
console.log(Egern.arguments); // { "key1": "value1", "key2": "value2" }

$argument

Surge 兼容参数(只读)。当配置中未提供 _compat.$argument 时,此变量不存在。

类型说明
string | undefined传递给脚本的参数字符串

示例

if (typeof $argument !== "undefined") {
console.log($argument);
}

console.log

日志输出。已重写以将日志传递到原生日志系统。

对象参数会自动序列化为 JSON 字符串。支持多参数,以 , 分隔。

示例

console.log("hello");
console.log("status:", 200, { key: "value" });
// 输出: "status:, 200, {"key":"value"}"

脚本类型

Request 脚本

在 HTTP 请求发送前执行,可以修改请求、直接返回响应或中止请求。

专属全局变量

$request — 当前 HTTP 请求对象。

属性类型说明
methodstringHTTP 方法("GET""POST" 等)
urlstring请求 URL
headersobject请求头键值对
bodystring | Uint8Array | undefined请求体(需配置 body_required

$done(result)

完成脚本执行。根据传入参数的不同,执行不同操作:

不修改请求(透传):

$done({});

修改请求:

$done({
method: "POST", // 可选,修改 HTTP 方法
url: "https://...", // 可选,修改 URL
headers: { ... }, // 可选,修改请求头
body: "..." // 可选,修改请求体
});

只需包含要修改的字段,未包含的字段保持不变。

直接返回响应(不发送原请求):

$done({
response: {
status: 200, // HTTP 状态码
headers: { ... }, // 响应头
body: "..." // 响应体
}
});

中止请求:

$done();

示例

// 添加请求头
const headers = $request.headers;
headers["X-Custom"] = "value";
$done({ headers });

// URL 重写
if ($request.url.includes("old-api")) {
$done({ url: $request.url.replace("old-api", "new-api") });
} else {
$done({});
}

// 直接返回 mock 响应
$done({
response: {
status: 200,
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ mock: true })
}
});

Response 脚本

在 HTTP 响应返回给客户端前执行,可以修改响应或中止连接。

专属全局变量

$request — 原始请求对象(只读),与 Request 脚本中的 $request 结构相同。

$response — 当前 HTTP 响应对象。

属性类型说明
statusnumberHTTP 状态码
headersobject响应头键值对
bodystring | Uint8Array | undefined响应体(需配置 body_required

$done(result)

不修改响应(透传):

$done({});

修改响应:

$done({
status: 200, // 可选,修改状态码
headers: { ... }, // 可选,修改响应头
body: "..." // 可选,修改响应体
});

中止响应:

$done();

示例

// 修改响应体
let body = $response.body;
body = body.replace("old", "new");
$done({ body });

// 添加响应头
const headers = $response.headers;
headers["X-Modified"] = "true";
$done({ headers });

// 修改 JSON 响应
const data = JSON.parse($response.body);
data.extra = "injected";
$done({ body: JSON.stringify(data) });

Schedule 脚本

通过 cron 表达式定时执行。

专属全局变量

$cronexpstring,当前的 cron 表达式。

$done()

完成脚本执行,无参数。

$done();

示例

// 定时检查并通知
$httpClient.get("https://example.com/api/status", function(error, response, data) {
if (error) {
$notification.post("检查失败", "", error.toString());
} else {
const result = JSON.parse(data);
if (result.status !== "ok") {
$notification.post("服务异常", "", "状态: " + result.status);
}
}
$done();
});

Generic 脚本

通用脚本,用于面板显示等场景。

专属全局变量

$input — 输入信息对象。

属性类型说明
purposestring用途标识
positionstring位置标识
panelNamestring面板名称(等于脚本名)

$triggerstring,触发原因。

$done(output)

完成脚本执行并返回输出。output 为 JSON 对象,可包含以下字段:

字段类型说明
titlestring面板标题
contentstring面板内容
iconstring图标名称
icon-colorstring图标颜色
background-colorstring背景颜色
stylestring样式

示例

// 显示网络信息面板
const ip = $network.v4.primaryAddress;
const ssid = $network.wifi.ssid;

$done({
title: "网络信息",
content: `IP: ${ip}\nWi-Fi: ${ssid}`,
icon: "wifi",
"icon-color": "#007AFF"
});

Network 脚本

在设备网络状态变化时执行。

专属全局变量

无专属变量。可通过 $network 获取当前网络信息。

$done()

完成脚本执行,无参数。

$done();

示例

// 网络变化时记录日志
const ssid = $network.wifi.ssid;
const ip = $network.v4.primaryAddress;
console.log("网络已变化 - SSID: " + ssid + ", IP: " + ip);

$persistentStore.write(ssid, "last_ssid");
$done();

错误处理

运行时会自动捕获未处理的异常和 Promise 拒绝,并调用 $done({})(不修改请求/响应透传)。建议在脚本中自行处理错误以获得可预测的行为。

try {
// 脚本逻辑
} catch (e) {
console.log("Error: " + e.message);
$done({});
}

注意事项

  • $done() 必须调用:每个脚本必须调用一次 $done() 来结束执行。未调用会导致脚本超时。
  • $done() 只能调用一次:重复调用会被忽略。
  • 请求/响应体:body 仅在脚本配置了 body_required: true 时可用。二进制 body 以 Uint8Array 形式提供。
  • 超时:脚本有执行超时限制,超时后引擎会强制终止脚本。