Skip to content

运行时 ​

ctx ​

所有 handler 的第一个参数。

字段内容
localeBCP 47,如 zh-CN
userId可选,用于限流或权益校验,不用于界面展示
settings包级 settings 的当前值,由字段 default 与用户在包详情页填写的值合并而成。所有 handler 均从此处读取包级设置,不应从 input.params 中查找。用法见 开发者指南 · 设置
http.get / http.post网络
html.load唯一 DOM API,返回 cheerio 句柄
storage.get / set / remove包私有 KV

运行时不提供全局宿主对象、其他 DOM API 或跨包共享的 KV 存储。

console ​

console.log / info / warn / error 由宿主记录,并显示在调试页中。参数会转换为字符串;对象应使用 JSON.stringify 序列化。每次 handler 调用的日志独立记录,不与结果缓存关联。

http ​

ts
ctx.http.get(url, options?)
ctx.http.post(url, body, options?)

返回 { status, headers, data }。对于非 2xx 响应,运行时不会自动抛出异常。

选项规则
headers请求头
query由 runtime 编码
timeoutMs可以缩短,但不能超过 App 设置的上限
followRedirects默认 true
cacheTtlSeconds按 method + URL + query 缓存 HTTP 响应
decompress可选

请求 origin 必须包含在包的 permissions.network 中,否则请求不会发送。

storage ​

存储作用域为包 id。同一包内的多个扩展共享存储,不同包之间相互隔离。

ts
ctx.storage.get(key)
ctx.storage.set(key, value, { ttlSeconds? })
ctx.storage.remove(key)

值必须能 JSON 序列化。

错误 ​

情况做法
请求成功但无数据返回空数组,或由 detail 返回 null
失败throw ExtensionError

ExtensionError:code、message(给用户)、retryable。

coderetryable典型原因
invalid_paramsfalse缺少关键词、枚举值无效
not_foundfalse详情不存在
rate_limitedtrue超出配额
unavailabletrue上游超时或 5xx
internalfalse脚本逻辑错误

普通 Error 会被统一转换为 internal 错误。

缓存 ​

声明写在扩展上。键:(packageId, type, extensionId, method, input)。

type / 方法默认 ttlSeconds
widget.load / search.search3600
widget.placeholder0(安装时单独写入磁盘,不进入结果缓存)
detail.load60
playback.sources0
subtitle.match / search3600
subtitle.file0
danmu.match / search / episodes3600
danmu.comments0

用户清理包缓存时,App 会同时清除该包的结果缓存、storage 和 HTTP 缓存。

权限 ​

ts
permissions: {
  network: string[];
}

未声明 network 或列表为空时,禁止发起 HTTP 请求。storage 默认可用。新增能力必须显式声明权限,未声明时默认拒绝。

扩展目录 ​

订阅 URL 应返回以下 JSON。Content-Type 不受限制,但响应正文必须是有效 JSON。目录信息从 definePackage 字面量中静态提取,提取过程不会执行 handler。format 仅支持 1;其他值会导致整份目录被忽略。

json
{
  "format": 1,
  "title": "示例源",
  "description": "可选",
  "updated": "2026-09-24T08:00:00Z",
  "packages": [
    {
      "id": "conflux.bangumi",
      "title": "动漫数据",
      "description": "每日播出与详情",
      "author": "可选",
      "icon": "https://example.com/icon.png",
      "version": "1.2.0",
      "engine": 1,
      "changelog": "修复时区",
      "types": ["widget", "detail", "playback"],
      "url": "https://example.com/packages/bangumi.js"
    }
  ]
}
字段必填含义
format是清单格式,仅支持整数 1
title是订阅源的展示名称
description否源说明
updated否清单生成时间,ISO 8601
packages是包列表,可为空数组
packages[].id是与 definePackage.id 相同,更新时用于匹配已安装的包
packages[].title是展示名
packages[].description否说明
packages[].author / icon否展示
packages[].version是semver 字符串,必须取自包的 version
packages[].engine是仅支持整数 1;其他值对应的条目会被忽略
packages[].changelog否当前版本的更新说明,使用 Markdown 纯文本
packages[].types是包内扩展 type 的去重列表
packages[].url是该包 .js 的 http(s) 地址

App 使用 types 筛选“可添加到 Dashboard”或“可作为弹幕服务”的扩展包。version 和 updated 必须为字符串,不能使用数字。