首页
/ ProxyPin脚本开发实战:用JavaScript轻松定制请求/响应处理逻辑

ProxyPin脚本开发实战:用JavaScript轻松定制请求/响应处理逻辑

2026-02-05 05:27:29作者:柯茵沙

你是否还在为抓包工具无法满足特定业务需求而烦恼?是否希望像专业开发者一样定制网络请求处理逻辑,却被复杂的编程语言和框架拒之门外?本文将带你使用JavaScript快速上手ProxyPin脚本开发,无需深厚编程基础,即可实现请求拦截、数据修改、响应伪造等高级功能。

脚本开发基础架构

ProxyPin采用Flutter框架开发,其脚本引擎基于flutter_js实现JavaScript运行环境,核心代码位于lib/network/components/js/script_engine.dart。该引擎提供了完整的请求/响应转换机制,通过convertJsRequestconvertJsResponse方法实现Dart与JavaScript数据结构的双向映射。

脚本管理器lib/network/components/manager/script_manager.dart负责脚本的加载、匹配和执行,其核心工作流程如下:

sequenceDiagram
    participant Client
    participant ScriptManager
    participant JSEngine
    participant Server
    
    Client->>ScriptManager: 发起网络请求
    ScriptManager->>ScriptManager: URL规则匹配
    ScriptManager->>JSEngine: 执行onRequest脚本
    JSEngine-->>ScriptManager: 返回修改后请求
    ScriptManager->>Server: 发送修改后请求
    Server-->>ScriptManager: 返回响应
    ScriptManager->>JSEngine: 执行onResponse脚本
    JSEngine-->>ScriptManager: 返回修改后响应
    ScriptManager-->>Client: 返回最终响应

快速入门:第一个脚本

ProxyPin提供了简洁的脚本模板,包含两个核心函数:

// 在请求到达服务器之前调用
async function onRequest(context, request) {
  console.log(request.url);
  // 示例:添加自定义请求头
  // request.headers["X-ProxyPin"] = "Hello";
  return request;
}

// 在响应返回客户端之前调用
async function onResponse(context, request, response) {
  // 示例:修改响应状态码
  // response.statusCode = 200;
  return response;
}

这个模板文件位于lib/network/components/manager/script_manager.dart,所有脚本都必须实现这两个异步函数。

核心API详解

请求对象(Request)

请求对象包含以下主要属性,可直接修改:

属性名 类型 描述
url String 请求完整URL
host String 域名
path String 请求路径
queries Object URL查询参数键值对
headers Object 请求头键值对
method String HTTP方法(GET/POST等)
body String 请求体文本内容
rawBody ArrayBuffer 原始二进制数据

响应对象(Response)

响应对象包含以下主要属性,可直接修改:

属性名 类型 描述
headers Object 响应头键值对
statusCode Number HTTP状态码
body String 响应体文本内容
rawBody ArrayBuffer 原始二进制数据

上下文对象(Context)

上下文对象包含执行环境信息:

{
  "scriptName": "脚本名称",
  "os": "当前操作系统",
  "session": "会话存储对象",
  "deviceId": "设备唯一标识"
}

实用场景案例

1. 请求头修改

以下脚本为所有API请求添加认证令牌:

async function onRequest(context, request) {
  // 匹配所有以/api/开头的请求
  if (request.url.includes("/api/")) {
    request.headers["Authorization"] = "Bearer YOUR_TOKEN";
    console.log("已添加认证头:", request.url);
  }
  return request;
}

2. 响应数据篡改

将JSON响应中的"vip"字段统一改为true:

async function onResponse(context, request, response) {
  try {
    // 仅处理JSON响应
    if (response.headers["content-type"]?.includes("application/json")) {
      const body = JSON.parse(response.body);
      if (body.user) {
        body.user.vip = true;  // 修改VIP状态
        response.body = JSON.stringify(body);
      }
    }
  } catch (e) {
    console.error("修改响应失败:", e);
  }
  return response;
}

3. 动态请求转发

将特定请求转发到测试服务器:

async function onRequest(context, request) {
  // 将生产环境API转发到测试环境
  if (request.host === "api.example.com") {
    request.host = "test-api.example.com";
    request.headers["Host"] = "test-api.example.com";  // 同步修改Host头
    console.log("请求已转发至测试环境");
  }
  return request;
}

4. 本地文件替换

使用本地文件替换网络请求响应:

async function onResponse(context, request, response) {
  if (request.url.endsWith(".json")) {
    // 读取本地JSON文件替换响应
    const localData = await fetch("file:///sdcard/test.json").then(r => r.json());
    response.body = JSON.stringify(localData);
  }
  return response;
}

高级功能:内置工具

ProxyPin脚本引擎内置了多个实用工具:

  • 文件操作:通过FileBridge访问本地文件系统
  • 加密功能:提供MD5工具进行数据哈希
  • 网络请求:完整支持Fetch API,可在脚本中发起新的HTTP请求
  • 会话存储:通过context.session在请求间共享数据

调试与日志

脚本中可使用console.log()输出调试信息,日志会显示在ProxyPin的控制台中。日志系统实现于lib/network/components/manager/script_manager.dart,支持多窗口日志分发。

调试时可通过以下方法查看请求详情:

async function onRequest(context, request) {
  console.log("请求URL:", request.url);
  console.log("请求头:", JSON.stringify(request.headers, null, 2));
  return request;
}

实战技巧与最佳实践

  1. URL匹配优化:使用正则表达式提高匹配精度,如/api/user/\d+/匹配用户ID
  2. 错误处理:始终使用try-catch包裹可能出错的代码
  3. 性能考虑:避免在脚本中执行复杂计算,影响请求响应速度
  4. 会话管理:利用context.session存储用户认证信息等跨请求数据
  5. 脚本组织:复杂逻辑建议拆分为多个函数,保持主函数简洁

常见问题解决

脚本不生效?

  1. 检查脚本是否启用,URL规则是否匹配目标请求
  2. 确认脚本没有语法错误,可通过console.log输出调试信息
  3. 查看应用日志,位于应用支持目录下的script.json文件

如何持久化存储数据?

除了context.session临时存储外,可使用文件系统持久化数据:

// 保存数据到文件
const data = { token: "xxx", expire: Date.now() + 3600000 };
await fetch("file:///data/data/com.proxypin/cache/config.json", {
  method: "POST",
  body: JSON.stringify(data)
});

// 读取数据
const config = await fetch("file:///data/data/com.proxypin/cache/config.json")
  .then(r => r.json());

通过本文介绍的技术,你已经掌握了ProxyPin脚本开发的核心能力。无论是移动端App测试、Web前端调试,还是API接口模拟,ProxyPin脚本都能帮助你高效完成工作。立即下载体验,开启你的网络调试进阶之旅!

登录后查看全文
热门项目推荐
相关项目推荐