移动端调试 HTTP 流量,长期是个麻烦事——Charles 只跑在 macOS/Windows,Fiddler 绑定 Windows,mitmproxy 纯命令行门槛高。ProxyPin 从一开始就走全平台路线(Android、iOS、Windows、macOS、Linux),用 Flutter 做壳、Kotlin/Native 写核心代理引擎,v1.2.8 这版把日常抓包中最频繁的"选一批、处理一批"和"改写请求再发"两个场景做了明显增强,值得拿出来聊聊。
多选:批量删除、导出、重放
之前在 ProxyPin 里想删掉一堆无关请求,只能逐条点删除;导出也是一条一条操作。v1.2.8 加了多选模式——长按某条记录进入多选,再逐条勾选或全选,然后统一执行删除、导出为 JSON/HAR、或批量重放。
批量重放是调试接口幂等性和并发压力时最直接的手段:选中 10 条登录请求,一键重放,立刻看到服务端是否正确拒绝了重复提交。
请求重写增强
请求重写(Request Rewrite)是抓包工具里最实用的"主动干预"能力:不用改客户端代码,在代理层把请求的 header、query 参数、body 甚至目标 URL 替换成你想要的值,再转发给服务端。v1.2.8 对重写规则做了增强,支持更细粒度的匹配条件和多动作组合。
一个典型场景——调试环境切换:客户端硬编码了 api.production.com,你想让请求打到测试环境 api.staging.com,只需要一条 URL 重写规则,手机上零改动。
证书安装:全平台信任流程
HTTPS 抓包的前提是中间人证书被客户端信任。ProxyPin 提供了 Bilibili 视频教程(BV1Qm42157Gk),但各平台命令行操作更快,下面给出关键步骤。
macOS 信任 CA 证书
ProxyPin 启动后会在 ~/.proxypin/ 下生成 CA 证书,用命令行直接加入系统信任链:
# 1. 启动 ProxyPin,导出 CA 证书到文件
# 在 ProxyPin GUI 中:设置 → SSL证书 → 导出根证书
# 假设导出路径为 ~/proxypin_ca.crt
# 2. 将证书加入 macOS 系统信任库
sudo security add-trusted-cert -d -r trustRoot \
-k /Library/Keychains/System.keychain \
~/proxypin_ca.crt
# 3. 验证证书已安装
security find-certificate -c "ProxyPin" /Library/Keychains/System.keychain
Android 7+ 用户证书信任
Android 7 以后,用户级证书不再被应用信任,需要把 CA 推到系统级目录(需要 root 或 Magisk):
# 1. 导出 ProxyPin CA 证书为 PEM 格式(同上步骤)
# 2. 计算证书哈希名(Android 系统证书目录要求此格式)
HASH=$(openssl x509 -inform PEM -subject_hash_old -in ~/proxypin_ca.crt | head -1)
sudo cp ~/proxypin_ca.crt /system/etc/security/cacerts/${HASH}.0
# 3. 重启生效
adb reboot
没有 root 的设备,可以用 Magisk 的 "Systemless Trust User Certs" 模块,一键把用户证书提升到系统级,免去手动拷贝。
iOS 证书安装与全信任
iOS 端在 App Store 直接安装 ProxyPin App,证书安装流程:
- 在 ProxyPin App 内点击「安装证书」,下载
.pem文件。 - 打开「设置」→「已下载描述文件」→安装。
- 进入「设置」→「通用」→「关于本机」→「证书信任设置」→把 ProxyPin CA 的开关打开。
第 3 步最容易遗漏——只安装描述文件不够,必须手动开启完全信任,否则 Safari 和 WKWebView 仍会拒绝中间人证书。
实战:用请求重写调试接口参数
下面模拟一个真实调试场景——客户端发来的请求缺少一个 X-Debug-Mode: true header,你想在代理层注入它,同时把响应里的 cache-control header 替换成 no-store,确保每次拿到最新数据。
ProxyPin 的重写规则在 GUI 中配置,但规则本身可以导出为 JSON,方便团队共享。以下是一个可导入的重写规则文件示例:
{
"name": "debug-mode-inject",
"rules": [
{
"match": {
"url_regex": "https://api\\.example\\.com/v2/.*",
"method": "GET"
},
"actions": [
{
"type": "add_header",
"header_name": "X-Debug-Mode",
"header_value": "true"
},
{
"type": "replace_response_header",
"header_name": "cache-control",
"header_value": "no-store"
}
]
}
]
}
在 ProxyPin 中导入步骤:设置 → 请求重写 → 导入规则 → 选择上述 JSON 文件。导入后所有匹配 api.example.com/v2/ 的 GET 请求会自动注入 debug header,响应的缓存策略也会被改写。
批量导出与自动化分析
多选导出为 HAR 格式后,可以用 Python 快速做统计分析。下面是一个可直接运行的脚本,从导出的 HAR 文件中提取所有请求的耗时分布:
#!/usr/bin/env python3
"""从 ProxyPin 导出的 HAR 文件中统计请求耗时分布"""
import json
import sys
from collections import defaultdict
def analyze_har(har_path: str):
with open(har_path, "r", encoding="utf-8") as f:
har = json.load(f)
entries = har.get("log", {}).get("entries", [])
if not entries:
print("HAR 文件中没有请求记录")
return
# 按 URL 域名分组统计耗时
timing_stats = defaultdict(list)
for entry in entries:
url = entry.get("request", {}).get("url", "")
# 提取域名
domain = url.split("//")[1].split("/")[0] if "//" in url else url
timings = entry.get("timings", {})
# 总耗时 = 各阶段之和(send + wait + receive 等)
total_ms = sum(v for v in timings.values() if isinstance(v, (int, float)) and v >= 0)
timing_stats[domain].append(total_ms)
print(f"共 {len(entries)} 条请求,覆盖 {len(timing_stats)} 个域名\n")
print(f"{'域名':<40} {'平均耗时(ms)':<15} {'最大耗时(ms)':<15} {'请求数'}")
print("-" * 85)
for domain, times in sorted(timing_stats.items(), key=lambda x: -max(x[1])):
avg = sum(times) / len(times)
print(f"{domain:<40} {avg:<15.1f} {max(times):<15.0f} {len(times)}")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("用法: python3 har_timing.py <proxypin_export.har>")
sys.exit(1)
analyze_har(sys.argv[1])
运行方式:
# 1. 在 ProxyPin 中多选目标请求 → 导出为 HAR
# 2. 用脚本分析
python3 har_timing.py proxypin_export.har
输出示例:
共 42 条请求,覆盖 3 个域名
域名 平均耗时(ms) 最大耗时(ms) 请求数
-----------------------------------------------------------------------------------------
api.example.com 320.5 1200 28
cdn.example.com 45.2 180 12
auth.example.com 210.0 350 2
这类分析在定位"哪个域名拖慢了页面加载"时非常直接。
选用建议与注意事项
ProxyPin 目前覆盖了日常抓包的核心需求,但有几个边界需要留意:
| 场景 | ProxyPin 表现 | 备注 |
|---|---|---|
| HTTP/HTTPS 抓包 | ✅ 完整支持 | 需正确安装并信任 CA |
| WebSocket | ✅ 可查看帧数据 | 不支持实时修改帧内容 |
| HTTP/2 | ⚠️ 部分支持 | 多路复用流展示不如 Charles 直观 |
| gRPC (Protobuf) | ⚠️ 二进制 body 需手动解码 | 可配合外部工具反序列化 |
| 大流量场景(>1000条/秒) | ⚠️ GUI 可能卡顿 | 建议用过滤规则缩小范围 |
上手路径建议:
- 先在桌面端(macOS/Windows/Linux)启动 ProxyPin,配好 CA 证书,确认浏览器 HTTPS 抓包正常。
- 手机连同一 Wi-Fi,设置 HTTP 代理指向桌面端 IP:端口,安装并信任移动端证书。
- 用请求重写规则做一次环境切换(production → staging),验证规则生效。
- 尝试多选批量导出 HAR,跑上面的 Python 脚本看耗时分布。
遇到证书信任问题,优先检查 iOS 的「证书信任设置」开关和 Android 的系统级证书目录——这两个是 90% 证书问题的根源。社区交流可以加 QQ 群(pE3U9IAkXC),反馈问题通常响应较快。