JavaScript 重写 API(v1)

需要带条件的 JSON 或文本转换时,可使用 JavaScript 正文规则。本章介绍 MintFlow 2.0.0 的 $MF API,并通过可导入示例说明完整流程。仅转换 JSON 时,也可选择 jq。

正文重写需要有效 MintFlow Pro 权限,包括符合条件且有效的试用。使用直连出口即可,无需远程 VPN 服务器。仅检查或修改你有权处理的流量。

1. 体验官方 JavaScript 示例

官方示例分别提供 jq 和 JavaScript 包。JavaScript 包仅匹配 https://jsonplaceholder.typicode.com/posts/1(允许查询参数),而非该服务的全部流量。

  1. 打开 HTTP → HTTP 重写,点工具栏导入按钮,再选从 URL…。使用 JavaScript 包原始文件,不要使用 GitHub 网页地址。也可下载后通过**选取文件…**导入。
  2. 导入会将脚本保存到本地,按需将 jsonplaceholder.typicode.com 加入域名捕获,并创建禁用的规则。检查源码与匹配表达式后再启用。URL 导入只获取一次,不是自动更新订阅。
  3. 启用 HTTP 处理,确保 TCP 端口 443 在范围内。HTTPS 需要安装并完全信任当前配置的 CA,详见捕获设置指南。必要时,禁用 HTTP/3可促使兼容客户端改用 TCP,但不解密 QUIC。
  4. 保存配置并启动或重启 VPN,解决编译错误或 Pro 限制。如果要用实时捕获检查结果,请先开始录制。
  5. 在 iPhone 或 iPad 打开 https://jsonplaceholder.typicode.com/posts/1,重新加载以获取新响应,避免只查看缓存。对比下列字段;实验后禁用演示规则并重启 VPN。

包使用 direction: "response"、bodyMode: "json"、apiVersion: 1 和 language: "javascript"。源码如下:

const body = $MF.resp.body;
body.title = "MintFlow JavaScript rewrote this JSON response";
body.mintflowDemo = {
  language: "JavaScript",
  method: $MF.req.method,
  working: true
};
$MF.done({ body });

JSON 模式已经提供解析后的对象,不要再对正文调用 JSON.parse,也不要对替换值调用 JSON.stringify。预期响应包含:

{
  "title": "MintFlow JavaScript rewrote this JSON response",
  "mintflowDemo": {
    "language": "JavaScript",
    "method": "GET",
    "working": true
  }
}

以上只展示部分预期字段;原来的 userId、id 和 body 保持不变。另一个 jq 示例使用 /todos/1,两条规则不重叠。两种导入请求同一个捕获后缀,不会重复添加;均省略优先级,新规则因此使用默认值 100。

示例经过包格式与脚本契约检查,不代表已经成功完成真实隧道测试;公共演示服务也可能变化。请在真实设备验证实际流量。

2. API 参考

每次调用由 MintFlow 提供一个冻结的 $MF 命名空间。

API含义
$MF.apiVersionAPI 版本,当前为 1。
$MF.req.url规范化的完整请求 URL。
$MF.req.method请求方法,如 GET、POST。
$MF.req.body当前请求正文,仅请求规则提供;响应规则不提供。
$MF.resp请求规则中为 null;响应规则中为响应对象。
$MF.resp.status响应状态码,如 200。
$MF.resp.body响应规则的当前响应正文。
$MF.context深度冻结的调用元数据,见下文。
$MF.done({ body: value })提交符合所选模式类型的替换正文。
$MF.done()完成调用,不修改当前正文。
$MF.fail({ code, message })报告脚本失败,不是网络拒绝操作。
$MF.log.debug/info/warn/error(message, fields?)受限诊断;消息为字符串,可选字段必须兼容 JSON。

上下文字段包括 url、direction(request 或 response)、method、contentType(字符串或 null)、requestID(调用标识字符串)、ruleName、status(响应状态码或 null)。标识符只用于诊断,不要依赖其内部格式。

命名空间及请求/响应容器均被冻结,但 JSON 模式中的正文值本身可修改。修改该值或创建新值后,必须明确提交。给这些对象的 URL、状态码或标头赋值,不是受支持的重写操作。v1 API 不提供标头集合,也不提供另一个方向的正文。

3. 完成与失败行为

每条执行路径都必须明确调用 $MF.done(...)、$MF.done() 或 $MF.fail(...)。仅修改 JSON、返回值或让程序自然结束,都不会提交重写。首次完成信号生效;应把完成调用放在对应分支末尾,不要在其后继续修改对象。

修改真实数据前,请检查响应状态和结构。以下用于 JSON 模式的响应规则:

const body = $MF.resp.body;
if ($MF.resp.status !== 200 || body === null ||
    typeof body !== "object" || Array.isArray(body)) {
  $MF.log.debug("Unexpected response shape; leaving body unchanged");
  $MF.done();
} else {
  body.title = "MintFlow JavaScript rewrote this JSON response";
  $MF.done({ body });
}

规则失败、输出无效或超时,都不会应用该规则的替换值,而是保留当前正文继续处理。之前成功的规则可能已修改正文。缺少完成调用或超时,还可能使同一规则链中的后续 JavaScript 规则被跳过。不要将脚本失败作为安全或广告拦截手段;需要拒绝时,应使用相应路由或 URL 拒绝规则。

4. JSON 模式与文本模式

  • JSON:正文是解析后的 JSON 兼容值,不一定是对象,也可能是数组、标量或 null。提交的数据必须兼容 JSON;循环引用、undefined、BigInt、函数、符号和非有限数字都不是有效输出。
  • 文本:正文和替换值都必须是字符串,可直接使用文本操作。如果在文本模式编辑 JSON,需要自行解析和序列化;通常直接选择 JSON 模式更简单。

下面用于匹配范围受限、设置为 bodyMode: "text" 的请求规则,替换一处文本:

const text = $MF.req.body;
$MF.done({ body: text.replace("demo=off", "demo=on") });

方向和正文模式在规则中设置,不在脚本中设置。配置文本使用 direction、type:javascript、body-mode、api-version;MFHRB 使用 bodyMode、apiVersion。配置语法中的 JavaScript 规则默认使用文本模式,因此 JSONPlaceholder 示例应明确选择 JSON。

5. 沙盒与限制

这是受限的正文转换环境,不是 Node.js,也不是通用浏览器脚本 API。不要依赖 Node 模块、网页 DOM、跨调用持久状态或其他代理应用的 API。网络访问被阻止,fetch、XMLHttpRequest、WebSocket 等功能已禁用。转换需要的信息应来自源码和当前调用。

  • MFHRB 中 JavaScript 源码最多 128 KiB;整个包最多 1 MiB。
  • 规则超时为 50–2000 ms,默认 500 ms。MFHRB 使用 timeoutMS,配置文本使用 timeout-ms。共享规则链的截止时间可能使实际剩余时间更短。
  • 替换正文最多 1 MiB;JSON 还有深度与节点数量限制。保持转换简短且有明确边界。
  • 每次调用最多记录 32 条日志、16 KiB 编码后日志内容。不要记录凭据或完整私密正文;日志用于诊断,不是捕获导出。

不会自动提供独立的 body、context、MF 变量,也没有 $request、$response、$done 别名。自己声明 const body = $MF.resp.body 是合法的。

6. 审查、测试与分享

在 HTTP 实验室使用有代表性的正文,以及正确的 URL、方法、方向、状态码和正文模式进行测试。加入意外结构测试,确认无关数据不变。导入验证的是语法,不是对所有响应的正确性。

若规则看似无效,请检查 Pro 权限、启用状态、HTTP 范围、当前 CA 信任、实际 URL 与方向、正文模式、明确完成调用,以及保存后是否重启 VPN。查看重写诊断中的失败、大小和时间限制。

通过 MFHRB 包分享一条审查过的规则及完整源码。修订时保持规则名和脚本名不变;重复导入会更新同一组归属规则/脚本,并再次禁用以供审查。仅有配置文本并不包含受管理脚本的源码。

配置参考 · HTTP 分析与 MFHRB

阅读本页 Markdown