ProxyPin 中文文档 下载 App

ProxyPin context 对象 脚本持久化与状态管理

context.storage:跨调用持久化

同一个脚本的每次 onRequest / onResponse 调用,都能读写同一份 context.storage。这是实现"记住上一次"、"累积状态"的关键:

function onRequest(context, request) {
  // 计数器:记录某个 API 被调用了多少次
  if (!context.storage['api-count']) {
    context.storage['api-count'] = 0;
  }
  if (request.url.includes('/api/')) {
    context.storage['api-count']++;
    context.log('API 调用计数: ' + context.storage['api-count']);
  }
  return request;
}

storage 的生命周期

复杂状态示例

// 实现简单的请求去重
function onRequest(context, request) {
  let key = request.method + ':' + request.url;
  
  if (context.storage['last-request'] === key && 
      Date.now() - context.storage['last-time'] < 500) {
    context.log('DEBUG: 500ms 内重复请求,跳过');
    return null;
  }
  
  context.storage['last-request'] = key;
  context.storage['last-time'] = Date.now();
  return request;
}

context.log:调试输出

脚本里的 console.log 在 ProxyPin 环境里可能不生效,用 context.log:

function onRequest(context, request) {
  context.log('拦截请求: ' + request.method + ' ' + request.url);
  context.log('请求头数量: ' + Object.keys(request.headers).length);
  return request;
}

日志可以在 ProxyPin 的脚本控制台或请求详情中查看。

context.sleep:延迟模拟

让 onResponse 延迟返回,模拟网络慢:

function onResponse(context, response) {
  // 只对 API 延迟,不影响静态资源
  if (response.url.includes('/api/')) {
    context.sleep(1500);  // 1.5 秒
  }
  return response;
}

sleep 是阻塞的——脚本会等待指定毫秒后继续执行。不要在 onRequest 里滥用 sleep,会导致请求还没发出去就卡住。

context.async:异步任务

需要做耗时操作时用 async:

function onRequest(context, request) {
  context.async(async () => {
    // 可以在这里做网络请求、文件操作等耗时任务
    context.log('异步任务开始');
  });
  return request;
}

注意:async 里的操作不能改变当前 request / response(因为请求已经发出)。适合做日志上报、统计采集等旁路操作。

实战:请求-响应对偶处理

最经典的 context 用法是在 onRequest 里存、onResponse 里取:

// 在请求里记录原始状态码期望值
function onRequest(context, request) {
  context.storage['expect-success'] = !request.url.includes('/error');
  return request;
}

// 在响应里对比
function onResponse(context, response) {
  if (context.storage['expect-success'] && response.statusCode >= 400) {
    context.log('⚠ 预期成功但实际失败: ' + response.statusCode + ' ' + response.url);
  }
  return response;
}