问题定位-03-Charles在App抓包中的实战经验
做 App 测试时,最常见的一种现场混乱是这样的:
- App 明明发了请求,但测试说自己没抓到
- 抓到了部分接口,但关键接口就是没有
- 页面报错了,但研发说后台没看到请求
- 同一个接口在浏览器里能通,在 App 里不通
这时候如果没有一个稳定的抓包工具,现场经常会变成纯口头对线。
而 Charles 的价值,恰恰是把这些分散现象拉回到同一条链路里:
- 设备到底有没有把请求走到代理
- HTTPS 到底有没有被正确解开
- 请求是没发、没到,还是回来的东西不对
- 同一条请求改参数、重放之后会发生什么
所以这篇文章不写安装流程,而是按现场实战来讲:
Charles在 App 抓包里最常见的用法- 为什么很多“抓不到包”根因并不在工具
- 抓到之后怎么让它真正变成排障证据
一、Charles 在 App 抓包里最有价值的,不是“看见请求”,而是“确认链路是否真实经过代理”
一提 App 抓包,默认目标往往是:
- 抓到某个接口
但现场更核心的问题往往是:
- 设备流量有没有真的经过代理
- 是所有流量都走代理,还是只有一部分
- HTTPS 是否可解
- App 是否做了额外证书校验
如果这些前置问题不先搞清楚,后面很容易误判:
- 以为后端没收到
- 其实是代理没生效
或者:
- 以为 App 没发请求
- 其实是 HTTPS 没解开,只看到 CONNECT
二、最常用的 5 类 Charles 场景
1. 确认 App 是否真正发出请求
这是最基础的一层。
当页面报错、按钮无响应、列表转圈时,先想确认的通常不是接口细节,而是:
- 有没有请求出去
- 请求打到了哪个域名
- 是不是打错环境了
这时 Charles 的价值非常直接:
- 能先把“发没发”这个问题钉住
2. 确认 HTTPS 链路是否打通
App 抓包最常见的问题之一,不是请求没有,而是:
- 只看到 CONNECT
- 看不到明文请求
这通常说明:
- HTTPS 代理证书没正确安装
- 设备信任链没打通
- App 做了证书校验或 SSL Pinning
3. 对比不同环境、不同设备、不同版本的请求差异
例如:
- Android 正常,iOS 异常
- 老版本正常,新版本异常
- 测试环境正常,预发环境异常
这类问题特别适合用 Charles 看差异,因为你能直接对比:
- 域名
- Header
- Body
- 返回码
- 返回结构
4. 复放和改包验证
当我怀疑问题不只是前端展示,而是接口本身存在边界问题时,常见动作包括:
- 重放请求
- 改 Header
- 改请求体
- 换参数再发
这对排查下面几类问题很有用:
- 参数问题
- 鉴权问题
- 环境问题
- 服务端返回不一致
5. 现场留证
很多 App 问题难推进,不是因为现象复杂,而是因为没有留下可复查证据。
Charles 很适合留这些内容:
- 原始请求
- 原始响应
- Header
- 请求时序
- 域名与路由去向
这对后续提单和协作非常重要。
三、App 抓包现场最常见的几个根因,不是“Charles 不好用”
很多“抓不到”的问题,根因其实很固定。
1. 代理根本没生效
例如:
- 手机没连对 Wi-Fi
- 没填对代理地址和端口
- 电脑和手机不在同一网段
- 代理设置被系统或 App 覆盖
这种时候你看到的不是异常请求,而是根本没有流量进来。
2. HTTPS 没解开
常见表现:
- 能看到连接,但看不到请求详情
- 只有隧道、没有明文内容
这通常意味着:
- 证书没装好
- 设备没信任
- App 自己做了更严格的证书校验
3. App 走了特殊网络链路
例如:
- 某些 SDK 走了系统外链路
- 某些请求绕过了系统代理
- 某些域名策略和普通接口不一样
这时候不能简单下结论说“App 没发请求”,而要先确认这类流量是否本来就不会经过代理。
4. 环境混了
例如:
- 同时连着测试、预发、生产域名
- 接口走了灰度域名
- CDN、网关、BFF 层返回结构不一样
不先把目标环境收窄,现场很容易把问题看乱。
四、一套更实用的最小抓包骨架
如果我现在要现场抓一个 App 问题,通常按这个顺序来。
1. 先确认代理路径
先问清楚:
- 手机连的是哪张网
- 电脑的 IP 是什么
- 代理端口是什么
- 设备是否已经配置代理
如果这一步没确认,后面都是空抓。
2. 先抓一个最简单的请求确认链路
例如:
- 打开首页
- 下拉刷新一个列表
- 点一个确定会发请求的按钮
目的是先确认:
- 流量能不能进入
Charles - 是否能看到目标域名
3. 再确认 HTTPS 是否可读
这一步要回答:
- 只能看到 CONNECT 还是能看到明文
- 哪些域名可读,哪些域名不可读
4. 最后再去做问题场景复现
例如:
- 登录失败
- 支付下单失败
- 页面白屏
- 某个按钮无响应
此时抓到的包才真正有分析价值。
五、更常用的 4 个实战动作
1. 先按域名过滤
App 流量经常很杂,尤其带上埋点、CDN、图片、日志上报之后。
更稳的做法通常是先按目标域名收窄,只看主业务接口。
2. 对比同一接口在成功和失败场景下的差异
例如:
- 成功登录一次
- 再失败登录一次
重点对比:
- Header 差异
- 请求体差异
- 返回码差异
- 服务端返回字段差异
3. 重放请求确认是不是后端稳定复现
如果页面表现异常,我经常会先把对应请求重放一遍,看:
- 是前端问题
- 还是后端接口本身稳定返回异常
4. 导出或截图保留证据
不要只现场看一眼。
重要问题会至少保留:
- 请求详情截图
- 响应详情截图
- 时间线说明
这会直接影响后续问题单质量。
六、最容易踩的几个坑
1. 把“抓不到包”直接理解成“没有请求”
实际上更常见的是:
- 代理没生效
- HTTPS 没解
- 流量没走代理
2. 抓到了大量包,但没有先过滤主业务流量
最后就会陷入:
- 图片一堆
- 埋点一堆
- 静态资源一堆
却还是没看清真正的业务接口。
3. 只看一次失败,不做成功失败对照
很多问题单靠一次失败很难判断到底哪里不对。
但成功和失败一对比,差异往往会非常明显。
4. 只看接口结果,不看环境和设备差异
例如:
- Android 某版本异常
- iOS 正常
如果不把版本、设备、环境一起带进来,结论会很虚。
七、真实案例:为什么 App 页面报“网络异常”,但后台同学说根本没看到报错
场景
一个 App 页面在点击“提交”后频繁提示“网络异常”。
前端同学说:
- 页面就是超时了
后台同学说:
- 服务日志里没看到对应报错
- 接口监控也没明显异常
现场一度怀疑是偶发前端问题。
执行
先用 Charles 抓这条提交链路,按下面顺序看:
- 先确认手机流量是否经过代理
- 再确认目标接口域名是否被正确抓到
- 再对比成功提交和失败提交两次请求
现象
结果并不是接口完全没发出去,而是:
- 失败场景下,请求实际上打到了另一个环境域名
- 这个域名对应的是旧网关
- 旧网关返回了不同格式的错误结构
- App 端没有兼容这个结构,统一兜成了“网络异常”
所以现场的误导点在于:
- 前端看到的是网络异常
- 后台主服务看到的是“没收到主域名请求”
双方都没错,但都只看到了自己那一层。
排查
继续往下看发现,问题出在新版本里一段环境配置切换逻辑没有完全生效,导致部分请求仍然走旧域名。
这个问题如果没有抓包,很容易一直在:
- 前端超时逻辑
- 后端错误处理
这些方向里绕圈子。
修复
最终修复动作很明确:
- 修正环境配置切换逻辑
- 再次抓包确认提交请求统一走到目标域名
- 增加提交流程的环境校验回归
这个案例很典型地说明:
Charles 在 App 抓包里最有价值的,不只是看到请求,而是把“到底请求打到了哪里”这件事钉死。
八、怎么把 Charles 用成稳定的测试能力
更合适的做法是把它沉淀成固定动作,而不是出了问题才临时打开。
至少固定这几条:
- 先确认代理链路再抓问题
- 先确认 HTTPS 是否打通再谈接口内容
- 先做成功失败对照再下结论
- 关键问题必须留请求、响应和时间线证据
这样 Charles 才不会只是一个“会抓包的人偶尔打开一下”的工具,而会真正成为 App 测试里的现场证据工具。
九、写在最后
Charles 在 App 抓包里的价值,不是让你多看几个请求,而是让你把设备、环境、代理、证书、接口和页面现象放回一条完整链路里。
很多看起来像“网络异常”的问题,最后根因并不在网络本身,而是在:
- 请求到底去了哪里
- HTTPS 到底有没有被正确解开
- App 到底拿到了什么返回
只要这几件事能被抓清楚,很多 App 现场问题就不会再停留在互相猜。