ProxyPin JavaScript 脚本引擎 QuickJS 运行时
脚本引擎的定位
请求重写能处理的场景:固定规则的重定向、Header 注入、Body 替换。一旦需要"当 A 条件时做 X,否则做 Y"、"记住上一次请求的结果"、"根据响应内容动态生成下一次请求参数"——请求重写搞不定了,这就是脚本引擎的用武之地。
ProxyPin 内置 QuickJS 运行时(轻量、兼容 ES2020、启动快),每个脚本独立运行,互不影响。
脚本生命周期
每个脚本可以定义两个核心钩子:
// 请求发出前执行——可以修改 request,也可以返回 null 让请求被屏蔽
function onRequest(context, request) {
return request; // 返回修改后的 request
}
// 收到响应后执行——可以修改 response
function onResponse(context, response) {
return response; // 返回修改后的 response
}
调用时机:
- App 发起请求 → ProxyPin 拦截 → onRequest 钩子 → 修改后发到服务器
- 服务器返回响应 → ProxyPin 收到 → onResponse 钩子 → 修改后返回给 App
两个钩子都可以不定义(不需要时不写)。
脚本的组成部分
一个完整的脚本需要:
- 脚本名称:便于管理,比如「自动注入测试 Token」
- 匹配 URL:正则表达式,决定这个脚本对哪些请求生效(可以留空匹配所有)
- 脚本代码:onRequest 和 onResponse 函数实现
可用对象和 API
context 对象(跨调用持久化)
function onRequest(context, request) {
// 存储数据,下次调用可以读取
context.storage['last-request-time'] = Date.now();
context.storage['api-version'] = 'v2';
return request;
}
context 还提供:
context.log(message)— 打印日志到 ProxyPin 控制台context.sleep(ms)— 延迟响应(模拟慢网络)context.async(task)— 异步执行耗时操作
request 对象
{
url: "https://api.example.com/users",
method: "GET",
headers: { "User-Agent": "...", "Authorization": "Bearer xxx" },
body: null, // POST/PUT 时有值
query: { "page": "1", "size": "20" }
}
可以直接修改这些属性(如 request.url = newUrl)。
response 对象
{
statusCode: 200,
headers: { "Content-Type": "application/json" },
body: "{\"code\":200,\"data\":{...}}",
url: "https://api.example.com/users",
duration: 150 // 毫秒
}
与请求重写的选择
| 场景 | 推荐方案 |
|---|---|
| 固定 URL 重定向 | 请求重写(配置简单) |
| 按条件注入 Token | 脚本 |
| 记住上一次请求结果 | 脚本(context.storage) |
| 替换固定字符串 | 请求重写 |
| 解析 JSON 后修改字段 | 脚本(需要 JSON.parse) |
| 模拟慢网络延迟 | 脚本(context.sleep) |
判断标准:需要 if/else 逻辑 → 脚本;纯静态替换 → 请求重写。