干过前后端联调的人都懂这个场景:接口返回不对,前端一口咬定"我请求没问题",后端很笃定"我接口没毛病",两边对着代码来回看,谁也说服不了谁。这时候把 Fiddler 打开,看一眼实际发出去的报文,问题基本当场就现原形——要么参数名拼错了,要么编码不对,要么响应头里藏了玄机。
今天这篇就把 HTTP 协议的基本格式和 Fiddler 的用法放在一起讲,因为这两件事本来就是一体的:抓包工具是你观察 HTTP 报文的眼睛,而懂协议格式你才知道自己在看什么。不夸张地说,把这两块吃透,日常排查接口问题、分析网页加载慢、定位前后端 Bug,效率能翻一倍。
内容覆盖从请求报文、响应报文的基本结构,到 HTTP 与 HTTPS、TCP 的关系,再到 Fiddler 的安装配置、抓包过滤、断点调试、弱网模拟、手机抓包,全程配合示例和实操经验,适合刚接触 HTTP 协议不久的开发者,也适合工作几年但一直靠"猜"排查问题的同学。
1. 先从一次抓包看懂 HTTP 请求报文的结构
HTTP 协议说穿了就是"客户端把请求按规定的格式写在纸上递给服务器,服务器再把响应按同样规则写回来"的一整套约定。整个请求报文由四部分组成:请求行、请求头、空行、请求体。看一次真实抓包比背一百遍概念都有用。
1.1 请求行:方法、路径、协议版本一个都不能少
请求行是报文的第一行,它包含三个要素:请求方法、请求路径、协议版本。中间用空格隔开。我自己抓包时最常看到的例子是这样:
GET /search?q=http&page=1 HTTP/1.1这一行拆开看:
GET是请求方法,表示想执行一次查询操作。/search?q=http&page=1是请求路径,/search是资源路径,问号后面是查询参数,用&连接多个键值对。HTTP/1.1是协议版本,客户端和服务器都得明白互相用的哪个版本。
请求方法常见的有 GET、POST、PUT、DELETE、PATCH、OPTIONS、HEAD。很多人把 GET 理解成"获取数据"、POST 理解成"提交数据",大方向没错,但严格说 GET 和 POST 并不能简单按"获取/提交"二分。POST 也能获取数据,GET 也能通过查询参数传数据,关键差别在于语义设计和实际约定:GET 一般被要求是幂等的、不改变服务器状态,POST 则没有这个约束,多用于创建或提交。实际开发中经常因为方法选错被网关拦截,比如有的接口强制只允许 POST,你发 GET 过去直接给你 405。
1.2 请求头:比想象中更容易踩坑的几个字段
请求头是紧接着请求行的若干行"键: 值"条目,负责传递请求的附加信息。随便抓一个网页请求,请求头通常长得像这样:
Host: www.example.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Accept: text/html,application/xhtml+xml Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 Connection: keep-alive Cookie: sessionid=abc123 Referer: https://www.example.com/previous-page这些头字段各管一摊事,但有几个特别值得单独说:
Host:指定目标主机和端口。HTTP/1.1 之后 Host 成为必选头,因为一台服务器可能同时托管多个域名,服务器要靠它区分你访问的是哪个站点。没有 Host 或者 Host 写错,很多服务器会直接返回 400。User-Agent:标识客户端类型。很多网站的接口会校验 UA,空 UA 或非浏览器 UA 会被反爬机制拦截。排查"浏览器能打开、代码请求却 403"之类的问题时,第一反应就应该是看 UA 有没有被服务端识别。Content-Type:只在有请求体的请求里出现,标记请求体的格式。常见的有application/x-www-form-urlencoded(表单)、application/json(JSON)、multipart/form-data(文件上传)。这个字段写错,后端解析器直接懵,最常见的报错就是"请求体解析失败"。Content-Length:请求体的字节长度。服务器要按这个长度去读请求体,如果长度和实际内容对不上,连接要么卡住要么直接断。很多抓包场景下你会看到 Content-Length 和实际 body 长度不一致,这种情况十有八九是代码里的字符串编码问题。
1.3 请求体:表单、JSON、二进制怎么区分
请求体不是每类请求都有。GET 请求绝大多数没有 body,POST、PUT、PATCH 一般都有。请求体的格式由 Headers 里的Content-Type决定,三种格式在 Fiddler 里的观感完全不一样。
表单格式是浏览器原生表单最常见的提交方式,编码方式是application/x-www-form-urlencoded,body 长这样:
name=zhangsan&age=28&city=beijingJSON 格式现在前后端联调用得最多,Content-Type: application/json,body 长这样:
{"name":"zhangsan","age":28,"city":"beijing"}文件上传用的是multipart/form-data,body 里会按 boundary 分隔多个部分,每个部分可以带自己的Content-Type,看起来是最"长"的一种格式。
这三种格式不能混用。后端如果写的是@RequestParam按表单解析,你硬发 JSON 过去,大概率收到一个 415 Unsupported Media Type;后端要 JSON,你发表单,参数又能取到但嵌套结构全丢。联调出问题时,先用 Fiddler 看一眼请求体的Content-Type和实际 body 格式对不对得上,这一步能排除大量低级问题。
2. HTTP 响应报文的读法:状态码和响应头一起看
响应报文的结构和请求报文对称:响应行、响应头、空行、响应体。先看响应行里的状态码,再看响应头里的上下文信息,最后看响应体里的实际内容,这是排查问题最有效率的路子。
2.1 状态码快速判断:不要只记住 200 和 404
响应行长这样:
HTTP/1.1 200 OK200是状态码,OK是原因短语。状态码按首位数字分五类:
| 状态码范围 | 含义 | 典型例子 |
|---|---|---|
| 1xx | 信息性响应 | 100 Continue、101 Switching Protocols |
| 2xx | 请求成功 | 200 OK、204 No Content |
| 3xx | 重定向 | 301 Moved Permanently、302 Found、304 Not Modified |
| 4xx | 客户端错误 | 400 Bad Request、401 Unauthorized、403 Forbidden、404 Not Found |
| 5xx | 服务器错误 | 500 Internal Server Error、502 Bad Gateway、503 Service Unavailable |
实际排查时,状态码只是方向标,不能只看它。200 不代表业务成功,很多后端设计是:HTTP 返回 200,业务结果放响应体里,比如{"code": 50001, "msg": "参数错误"},这种设计下你把 200 全当成功处理,用户侧就会出现"明明显示失败,网络面板里却是绿色 200"的诡异现象。反过来,5xx 也不等于后端代码真的挂了,比如 502 可能是代理层或网关重启导致的,重新请求一次就好了;503 多半是服务过载或维护中,后端代码可能活得好好的。
2.2 响应头里藏着决定页面表现的关键信息
响应头里值得重点关注的字段,我在工作里基本靠这几个做判断:
Content-Type:响应体格式,浏览器按它决定怎么渲染。JSON 接口如果被错误返回成text/html,前端res.json()会直接抛异常,这就是那种"后端说能用、前端说解析不了"的经典矛盾来源。Content-Length和Transfer-Encoding:这对字段有点相爱相杀。正常的响应靠Content-Length指明长度,下载进度条就是依赖它算进度的。但如果响应是服务端动态生成的,不确定长度,就会改用Transfer-Encoding: chunked分块传输,每块前一行标十六进制长度,最后一块长度为 0 表示结束。所以你在 Fiddler 看到响应头里没有 Content-Length 而有 Transfer-Encoding 时,别觉得奇怪,这是正常的流式传输。Set-Cookie:服务器让客户端种下的 Cookie。联调登录接口时,登录失败但状态码是 200,可能就是这里少种了一个关键 Cookie;反过来说,种多了或域不对,也会造成奇怪的"已登录但频繁跳登录页"现象。Cache-Control和Expires:控制浏览器缓存策略。排查"页面改了但打开还是旧的"这类问题时,先看这两个头字段,Cache-Control: no-cache意味着强制重新验证,没有缓存头则可能被启发式缓存。Location:配合 3xx 状态码使用,告诉客户端重定向目标地址。登录回调、短链跳转都靠它。
2.3 响应体实际长什么样
响应体是服务器真正返回的数据。HTML 页面返回的就是 HTML 源码,接口返回的通常是 JSON 或 XML。在 Fiddler 的 Inspectors 里切换 TextView 或 JSON 标签可以直接格式化查看,比在浏览器开发者工具的网络面板里看更接近"原始模样"。
排查问题时,响应体能帮你确认"服务器认为的正确结果"到底是什么。比如参数传错了,后端返回的错误信息里往往会写明期望格式,一看就懂。如果响应体是一堆压缩乱码,记得在 Fiddler 里勾选解压或看 Raw 标签,因为开启了 gzip 压缩的响应,明文视图里是解读不了的。
3. 抓包之前,把 HTTP 和这几层关系捋清楚
不先把几个概念捋顺,抓包的时候会遇到各种"这跟我理解的不一样"的困惑。这里挑三个最常被问的关系讲清楚。
3.1 HTTP 和 HTTPS 的差别就是中间多了一层 TLS
HTTP 是明文传输,请求和响应在网络上裸奔,中间任何一跳设备都能看到内容。HTTPS 本质上就是"HTTP over TLS",在 HTTP 和 TCP 之间多了一层 TLS(SSL 是它的前身)。客户端和服务器先通过 TLS 握手协商出一个对称加密密钥,之后传输的内容全部加密;同时通过证书机制让客户端验证服务器的身份,防止中间人冒充。
抓包工具抓 HTTPS 的原理很巧妙:Fiddler 把自己伪装成服务器的"替身",客户端跟 Fiddler 建立 TLS 连接,Fiddler 再以客户端身份跟真实服务器建立 TLS 连接。两边各自独立加密,Fiddler 在中间解密一边、再跟另一边通信,所以它能明文看到抓到的内容。前提是客户端要信任 Fiddler 的 CA 根证书,不然客户端会发现"服务器证书不是可信 CA 签发的",直接拒绝连接。这就是为什么 Fiddler 抓 HTTPS 的第一步永远是装它生成的根证书。
3.2 HTTP 和 TCP:一个管格式,一个管传输
HTTP 是应用层协议,TCP 是传输层协议。HTTP 只管"报文怎么写",不管"数据怎么安全完整地送过去";TCP 负责把字节流切割成数据包、按序传输、丢包重传、流量控制和拥塞控制。
用个生活类比:HTTP 是快递单上的填写规范,TCP 是物流运输系统本身。你只管按规范填单子,至于车怎么开、货怎么送、丢了怎么补,那是物流网络的事。所以抓包工具能看到的 HTTP 报文已经是应用层的东西,而 Wireshark 那一类工具才能看到 TCP 的 SYN、ACK、SEQ 这些底层机制。遇到请求慢、连接被重置这类网络层问题,光看 HTTP 报文有时候不够,得结合 Fiddler 底部的状态信息或改用 Wireshark 看 TCP 层的表现。
3.3 HTTP 连接复用:为什么一个 TCP 连接能发好多请求
早期 HTTP/1.0 时代,每次请求都要新建一个 TCP 连接,做完就断开。网页上有 100 个资源就要建立 100 次 TCP 连接,每次都有 TCP 三次握手的开销,性能很差。后来 HTTP/1.1 引入了Connection: keep-alive,让多个请求复用同一个 TCP 连接,这就是连接复用。
Fiddler 里观察连接复用非常直观:同一 Host 的多个请求,如果都有Connection: keep-alive,而且时间挨得很近,Fiddler 会话列表里还能看到部分请求用了同一条隧道。连接复用能大幅降低建立连接的时延和服务器压力,但也有副作用:如果服务器限制空闲连接超时,客户端还傻傻地维持长连接,下次请求时连接可能已被服务端关闭,客户端会收到一个 RST 包,然后重建连接。有些请求偶尔第一次发过去就失败、重试才成功,多半就是这个原因。
另外一个和连接复用相关的概念是 HTTP/2 的多路复用:单个 TCP 连接上同时并行多个请求和响应,彻底解决了 HTTP/1.1 队头阻塞的问题。Fiddler 新版和 Fiddler Everywhere 对 HTTP/2 的支持比旧版好,抓 HTTP/2 流量时记得开启相应选项,否则看到的可能是降级后的 HTTP/1.1 报文,容易误判。
4. Fiddler 安装和配置:代理工作原理是理解一切的前提
用 Fiddler 之前,先花两分钟搞懂它的"身份":Fiddler 本质就是一个本地代理服务器,默认监听本机 8888 端口。几乎所有它"能抓"和"抓不到"的问题,都能用这个代理身份解释。
4.1 下载选型:Classic 还是 Everywhere
Fiddler 现在有两条产品线:Fiddler Classic(经典版,免费)和 Fiddler Everywhere(跨平台,收费,国内我用的时候需要登录账户)。Classic 只支持 Windows,功能覆盖日常抓包、断点、弱网模拟、脚本定制,够用且顺滑。Everywhere 支持 Windows、macOS、Linux,界面现代化,但核心逻辑和 Classic 一致。
我的建议是:主力机是 Windows 就先用 Classic,零成本、资料多、稳定;如果你在 mac 上开发,或者想要更好的 UI 体验和团队协作能力,再考虑 Everywhere。另外再补充一句,Charles 和 whistle 也是同类工具——Charles 在 mac 圈用得多,whistle 是 Node 生态、支持配置化,各有优势。但如果你想系统搞懂 HTTP 格式,Fiddler 的 Inspector 和 Raw 视图是最直观的,新手强烈建议从它入手。
4.2 代理设置:Fiddler 在中间扮演了什么角色
Fiddler 启动后会自动把 Windows 系统代理设置为127.0.0.1:8888,只有当你关闭 Fiddler 或手动取消勾选时系统代理才会恢复。也就是说,你的浏览器和操作系统里所有走 HTTP/HTTPS 的请求,都会先发到127.0.0.1:8888,Fiddler 再代为转发给真正的目标服务器。响应回来也先经过 Fiddler,再转发给你的客户端。
理解了这一点,排查抓不到包的问题就有思路了:
- 如果 Fiddler 开着但浏览器请求不进来,先看菜单栏
File下的Capture Traffic是否勾选,再检查系统代理是否被其他工具覆盖(比如某些加速器或二次代理工具会改写系统代理)。 - 如果某些软件不走系统代理(比如用 WinHTTP 的系统服务、部分命令行工具),Fiddler 就抓不到。需要在命令行里临时设置代理环境变量,或者用 Fiddler 的
WinConfig功能去启用 Windows 回路代理。 - 如果浏览器装了代理管理插件,插件可能把流量引到别的代理,Fiddler 自然抓不到。这种问题第一排查点永远是"流量到底走了哪个代理"。
4.3 HTTPS 解密:装证书和装对证书是两回事
Fiddler 抓 HTTP 请求,开箱即用;抓 HTTPS 不做配置,只能看到一串 CONNECT 请求,看不到里面内容。原因是 Fiddler 跟客户端建立 TLS 连接时,需要客户端信任 Fiddler 的根证书。步骤不复杂:
- 打开
Tools -> Options -> HTTPS,勾选Decrypt HTTPS traffic。 - 弹出的提示框确认,然后点旁边的
Actions -> Trust Root Certificate,把 Fiddler 的根证书安装到 Windows 的受信任根证书列表。 - 重启 Fiddler,重新发起 HTTP 请求,就能看到明文内容了。
这里面有三处容易踩坑:
- 安装证书后浏览器仍提示"您的连接不是私密连接",大概率是 Fiddler 根证书没有被导入到正确的证书存储区。浏览器一般会读取 Windows 的"受信任的根证书颁发机构"存储区,如果你装到了"个人"存储区,认不了。建议通过 Fiddler 的
Actions -> Export Root Certificate to Desktop导出证书文件,再双击安装到"受信任的根证书颁发机构",更稳妥。 - iOS 手机抓包时,光下载描述文件不行,还要到
设置 -> 通用 -> 关于本机 -> 证书信任设置里把 Fiddler 证书的开关打开。这个步骤经常被漏掉,漏掉的结果就是"装了证书也抓不到 HTTPS"。 - Android 7.0 及更高版本默认不信任用户安装的 CA 证书,只有应用自身声明了信任用户证书(在 network security config 里配置)才会信任。所以抓 Android 应用的 HTTPS 流量,常常需要应用开发阶段关闭证书校验,或者在测试包中配置信任用户证书,否则只能看到 CONNECT 行。
5. Fiddler 日常操作:筛会话、看报文、改请求
Fiddler 的界面刚打开时有点信息爆炸:左边一大片会话列表,右边上半是请求详情、下半是响应详情,下面还有一条 QuickExec 命令行。实际用起来,核心操作就那几个,一个个说。
5.1 会话列表怎么看:图标和字段都不是摆设
会话列表每一行对应一次完整的 HTTP 请求-响应事务。顶部字段含义如下:
#:请求序号,从 1 开始递增,是定位会话最直观的标识。Result:HTTP 状态码,如 200、404、500。Protocol:协议版本,常见 HTTP/1.1,也有 HTTP/2。Host:目标主机名。URL:请求路径和查询参数。Body:响应体大小,单位是字节。Content-Type:响应内容的媒体类型。Process:发起该请求的进程名和 PID。Comment:手动备注。
列表左边的图标也有讲究。默认蓝色箭头表示请求已发出并收到响应;红色向下箭头表示请求失败或连接错误;浅蓝色箭头表示响应是从缓存读取的;灰色圆形表示请求被保留或断点挂起。双斜线图标表示该会话使用了隧道(比如 CONNECT 隧道)。我自己的习惯是:先按#从大到小看最新的几个请求,再按Result状态码排列,红色和 5xx 先处理。
5.2 过滤器:从上百条请求里精确找到目标
打开一个复杂页面,Fiddler 瞬间能抓到一两百个请求,不筛根本看不过来。最快的筛选方式是在工具栏底部的 QuickExec 命令行输入:
?keyword回车后会立刻过滤出 URL 中包含 keyword 的会话。比如?api会把所有路径带 api 的请求都筛出来。这个命令是我日常使用频率最高的一个。
更精细的过滤在右侧Filters标签页:
- 勾选
Use Filters后,可以按 Host、Client Process、Request Headers 等条件过滤。 Show only the following Hosts:把自己服务端的域名填入,其他全隐藏。Hide 304s:把缓存重定向响应隐藏掉,省得每次看一堆 304。Show only HTML/Show only IMAGE/Show only JS/CSS:限制只看特定资源类型。
调试接口时,我一般会在 Filters 里限定 Host 和Show only Content-Type为 JSON 的请求,这样列表里剩下的基本就是目标接口和它依赖的静态资源,定位效率很高。
5.3 Inspector 拆报文:Chrome 也能干这活,但 Fiddler 更细
双击任意会话,右侧 Inspector 区就能看到这个请求完整的请求参数和响应内容。Inspector 分为上下两块:上半块是请求,下半块是响应。
请求部分有几个常用标签页:
Headers:请求行 + 请求头的键值对视图,适合快速查看关键头字段。WebForms:把表单格式的请求体自动解析成键值对,查表单参数最方便。JSON:格式化显示 JSON 请求体。Raw:把完整原始报文一行行显示,想看"原汁原味"的报文格式就切到这里。
响应部分类似,多了Caching、Cookies、TextView等标签。其中TextView是最实用的——它直接把响应体以文本形式渲染,JSON 就显示 JSON,HTML 就显示 HTML。如果响应内容显示乱码,注意右下角有个编码下拉框,把 UTF-8 改成 GBK 或反过来,就能正常显示。
Chrome 开发者工具里的 Network 面板也能做类似的事,但 Fiddler 有个不可替代的优势:它处于客户端和服务器之间的代理位置,能拦截和篡改,而浏览器内部工具只能观察。另外 Fiddler 能抓非浏览器客户端的流量,任何遵守系统代理的软件它都能管,Chrome 面板管不了。
5.4 Composer:什么都不改直接重放一遍
调试接口时经常需要"原样重放一次请求"看服务端是稳定复现问题还是偶发。这个需求在 Fiddler 里的操作路径是:在会话列表里右键一个请求,选择Replay -> Reissue Requests,快捷键是R。它会在不打开界面的情况下重新发送完全相同的请求。
如果想手动改一下参数再发,三个入口:
- 右键会话 ->
Replay -> Edit and Reissue。 - 直接把会话拖拽到右侧的
Composer标签页。 - 在 QuickExec 命令行选中某个会话,输入命令打开 Composer。
Composer 里的请求可以随手改:URL 路径、请求头、请求体。改完点Execute,Fiddler 会把构造好的请求立刻发出去,新的会话出现在列表顶部。排查"参数错没错"和"服务端在不同请求头下的表现差异"时,这个功能比反复改代码重新跑省太多时间。
6. 把 Fiddler 用成接口联调工具:断点、弱网、手机抓包
到这里,抓包、筛包、看报文这些基本功就有了。但 Fiddler 的价值不止于"看",还能"改"和"模拟"。断点调试和弱网模拟是两类最高频的实操场景。
6.1 断点调试:前端说没发请求时的终极裁决
Fiddler 的断点能力分两种:
Before Request:请求从客户端发出、尚未到达服务器前拦截住。After Response:响应从服务器返回、尚未送达客户端前拦截住。
菜单入口在Rules -> Automatic Breakpoints,快捷键分别是F11和Alt+F11。开启后,命中断点的请求会在会话列表里显示为红色竖条图标,右侧 Inspector 会进入可编辑状态。在请求断点时,你可以修改请求头、请求体,然后点Run to Completion放行;改动的内容会被 Fiddler 代替原请求转发给服务器。
这招在两类场景里特别好用:
场景一:前端说"我发出去的参数是对的",你直接在断点里检查客户端发来的参数,一眼看出参数名写错还是某个字段丢了。这比反复在代码里打日志来得快得多。
场景二:你想验证"如果请求里加个头会怎样"。在断点里手动加一行X-Token: abc123再放行,观察服务端对这个头怎么响应,不用改任何前端代码就能做实验。
响应断点同理:请求已经回来了,你可以在到达浏览器前把响应内容改成{"code": 0, "data": []},再放行给前端,前端看到的结果就是"接口正常返回空数据"。这样可以把一种异常情况变成可稳定复现的测试场景。
注意断点开着的时候,所有会话都会挂在红色状态,别忘记用完立刻关掉断点开关,否则后续请求全卡住。我第一次用时就因为忘了关,傻等半天。
6.2 弱网模拟:模拟 2G/3G 网速不用真找信号差的房间
弱网测试是移动端开发绕不开的环节。Fiddler 模拟弱网不需要真去电梯间,原理是给每个经过代理的请求和响应人为注入延迟,甚至主动丢包重发。
最简单的姿势是用菜单里的模拟限速开关:Rules -> Performance -> Simulate Modem Speeds。它模拟的是一套 56K 猫速率的拨号网络,网速压得很低,大概只适合演示,不适合精确控制。
真正精细的控制要写 FiddlerScript。在Rules -> Customize Rules打开的脚本文件里,找到OnBeforeRequest和OnBeforeResponse两段函数,往里加一段延迟逻辑:
if (m_HitCount % 5 == 0) { // 模拟随机丢包:服务端 5 个请求里 1 个不响应 oSession["x-pkt-drop"] = "1"; } if (oSession.HostnameIs("api.example.com")) { // 只对特定域名模拟 3G 网络延迟:上行 100ms,下行 200ms oSession["request-trickle-delay"] = 100; oSession["response-trickle-delay"] = 200; }改完脚本保存,Fiddler 会自动重新加载。request-trickle-delay的单位是毫秒,表示每 KB 数据延迟多少毫秒。这两行脚本的意思就是:目标域名的每个请求每发 1KB 额外等 100ms,每收 1KB 额外等 200ms,粗略相当于 3G 网络的下行速度。对超时时间短的接口,这招能轻松压出"请求超时"的异常路径。
弱网测试的关键不只是"变慢",而是要看系统在超时、重试、加载失败时的表现:加载提示是否正常、超时时间是否够用、失败重试会不会打出重复请求。用 Fiddler 模拟弱网做一次完整的首屏加载测试,很多线上问题靠这个就能提前暴露。
6.3 手机和 WebSocket 的抓包要点
手机抓包是移动端开发高频需求。让手机流量走 Fiddler 的步骤不复杂,但细节不少:
- 电脑和手机连同一个局域网。
- Fiddler 里确认允许远程连接:
Tools -> Options -> Connections勾选Allow remote computers to connect,记住端口 8888,改完重启 Fiddler。 - 手机连上同一 Wi-Fi,在 Wi-Fi 设置里将代理设为"手动",主机填电脑的局域网 IP,端口填 8888。
- 这时能抓到手机上的 HTTP 流量;抓 HTTPS 还需要在手机浏览器里访问
http://电脑IP:8888,下载 Fiddler 根证书并安装信任。
做完上面的步骤,你可以顺手检查一下 Windows 防火墙,别把 8888 端口拦了,否则手机连不上代理。电脑的局域网 IP 优先找 IPv4 地址,别填物理网卡的虚拟地址。
再说 WebSocket。Fiddler 对ws://和wss://的抓包是通过 CONNECT 隧道实现的,默认可以捕获,但要在会话列表里区分它:WebSocket 请求通常显示为101 Switching Protocols,会话图标上带一个"WORLD"或类似标记。抓取成功后,右侧 Inspector 里会出现一个WebSocket标签页,点开能看到每一帧 WebSocket 消息的 payload 和方向(客户端发给服务器还是服务器推给客户端)。调试实时聊天、通知推送这类功能时,这个视图能直接回答"服务器到底推没推消息,推的是什么"。
如果在 Fiddler 里看不到 WebSocket 标签,检查一下是否开启了 HTTPS 解密,因为wss://同样要走证书链路;另外最新版 Fiddler 对 WebSocket 帧的展示有些小改动,但整体逻辑不变。
结尾
写到这里,HTTP 报文格式和 Fiddler 的核心用法就算过了一遍。我自己用了这么多年抓包工具,最大的体会是:协议格式的知识和抓包工具是互相成就的——懂格式的人手里有工具如虎添翼,只有工具不懂格式的人看到满屏报文会慌。你不用把所有头字段全背下来,先把请求行、Host、Content-Type、状态码、Content-Length 这几个最关键的吃透,日常联调就够用了,其他字段遇到再看。
最后分享一个我自己的小习惯:每次排查完一个接口问题,我会顺手在 Fiddler 里给那个会话加个 Comment 备注,写清楚"问题根因是什么、哪个字段导致";攒上两个星期再回看,就是一本非常实用的踩坑日志。这个动作花不了十秒,但对熟悉自己项目的边界、快速命中同类问题帮助很大。你不需要做到面面俱到,先从一次完整的抓包、看懂一个报文的请求行和状态码开始,这一套动作下来,你就能体会到为什么大家都说"数据在手,问题我有"。