上周联调排一个接口问题折腾了两个小时没头绪。接口在浏览器开发者工具里明明显示200服务端日志也确认收到了请求但页面就是渲染不出最新数据。后来把Fiddler抓包打开重新走了一遍流程才发现请求在到达服务端之前被一层本地代理缓存截住返回的是旧响应。这种场景光靠F12根本看不出来。Fiddler抓包配合浏览器开发者工具是我这几年排查HTTP/HTTPS接口问题最顺手的一对搭配一个看应用内部视角一个看网络中间链路互相补位。这篇内容适合所有每天跟接口打交道的人前端开发、客户端开发、测试、运维以及刚入门想搞懂网络请求细节的同学。我会从最基础的环境配置讲起再走一遍完整抓包排查流程最后聊移动端抓包和规则自动化以及和开发者工具配合时的一些实操习惯。1. 为什么排查问题不能只依赖开发者工具1.1 开发者工具的边界在哪里浏览器开发者工具是每一个前端同学最常用的调试入口Network面板能看到请求URL、Header、Payload、响应JSON还能看耗时和水瀑布图。坦白说日常开发里大部分问题在这一步就能解决。但它的定位决定了它有盲区它只能看到当前浏览器页面上下文里发出的请求而且是站在浏览器内部视角去观察。换句话说F12给你看的是浏览器认为它发生了什么而不是网络链路上真实发生了什么。常见的几个盲区包括桌面客户端、移动App、小程序、IoT设备这类非浏览器程序发出的请求开发者工具完全看不到。浏览器自动跟随重定向的处理过程。比如服务端先返回302浏览器再请求Location地址开发者工具里往往只显示最终那一条请求记录中间跳转细节被隐藏了。请求是否被Service Worker、浏览器插件、本地代理缓存拦截开发者工具里有时会标注来源但不会给你完整的链路。原始响应字节。开发者工具一般会自动解码gzip等压缩内容你看到的是已经处理好的结果而Fiddler能看到更原始的返回。本地缓存命中特别是某些反向代理环境下响应到底是来自源站还是缓存层开发者工具不直观。所以我一直有个习惯浏览器开发者工具负责定位“哪个请求有问题”Fiddler负责回答“这个请求到底在链路上经历了什么”。1.2 Fiddler的核心定位中间人代理Fiddler的本质是一个本地HTTP/HTTPS代理。启动之后它会在本机监听一个端口系统或者应用程序通过这个代理发出的流量都会先经过Fiddler再转发到目标服务器。响应返回时也一样先从服务器到Fiddler再回到应用程序。站在中间的视角你就能看到完整的请求字节和响应字节。可以先简单理解一下分工对比维度浏览器开发者工具Fiddler主要定位浏览器内部前后端交互可视化应用与服务器之间的中间人代理流量来源当前浏览器页面和相关Worker所有走代理的程序包括桌面端、AppHTTPS解密内置自动解密无感需要安装并信任根证书可选择性解密请求断点修改基本不具备内置断点可在请求前后修改请求重放部分场景支持简单重发支持编辑、保存、批量重放跨端调试仅限浏览器PC、手机、虚拟机、远端设备都可以响应模拟基本不具备AutoResponder可返回本地文件或自定义内容Fiddler这个“中间人”身份很多人第一反应是它能解密HTTPS那是不是很危险其实它就是一套标准的本地调试工具和开发者工具看到的原理类似只不过它自己充当了证书签发角色。我们用它抓自己的应用流量、修改自己的请求做联调都是正常开发工作流的一部分。2. 环境准备安装、代理配置与HTTPS证书2.1 下载安装和系统代理Fiddler的安装不复杂我常用的经典版本装完大概几十MB安装过程一路下一步即可。首次启动后它默认会开启系统代理端口是8888。打开Fiddler以后你在系统设置里能看到代理被设置为127.0.0.1:8888所有走系统代理的浏览器请求都会经过它。这里有一个很多人第一次用会懵的点开着Fiddler浏览器能上网关了Fiddler浏览器也还能上网那代理到底生效没有只要Fiddler还开着代理就生效如果正常退出Fiddler系统代理会自动还原。但有一种情况要注意Fiddler如果崩溃或者被任务管理器强杀系统代理可能没被还原这时候你会发现浏览器突然上不了网。解决办法不是重装Fiddler而是去系统互联网设置里手动把代理关掉或者重新启动Fiddler再正常退出一次。抓包的第一个动作通常是清空会话列表然后重新触发一次请求。我习惯按CtrlX清空全部或者用过滤器只看某几个域名避免会话一多看不清。2.2 HTTPS解密原理和证书安装不装证书的情况下Fiddler也能抓到HTTPS请求但只能看到域名和端口请求体和响应体都是加密的看不到明文。要抓明文必须做HTTPS解密。解密流程大概是这样的客户端连上Fiddler以后Fiddler会用它自己的根证书临时伪造成目标网站的证书下发给客户端。客户端因为信任了Fiddler的根证书所以接受了这个伪造证书。之后客户端和Fiddler之间的流量用这个伪造证书加密Fiddler和真实服务器之间再用真实证书加密Fiddler在中间同时持有两端解密的钥匙自然就能看到明文。具体操作两步在Fiddler菜单里打开Tools Options HTTPS勾选“Decrypt HTTPS traffic”弹窗里确认安装根证书。在同一个面板点Actions Trust Root Certificate把根证书安装到系统受信任的根证书颁发机构里。操作完成后最好重启一次浏览器并且把浏览器里已经打开的页面全部刷新一遍。否则里面有些走了HSTS强制安全连接的站点可能会因为证书突然变化而直接拒绝连接。证书这块我踩过一个很典型的坑系统时间不对。有一台测试机系统时间被改到了半年前装上Fiddler证书以后所有HTTPS请求都报证书过期。查了半天才发现是时间校准问题因为证书有效期校验对不上。所以装证书之前先确认一下系统时间是否正确。2.3 常见环境配置问题抓不到localhost请求。浏览器访问127.0.0.1或localhost时默认会绕过代理Fiddler也看不见。需要在Fiddler的连接设置里把“Bypass proxies for localhost”取消勾选或者在过滤器里手动包含本地地址。系统代理被其他工具抢占。很多网络工具也会改系统代理先启动Fiddler再启动其他工具有可能导致代理设置被覆盖。排查时可以先关掉其他网络代理工具。只想抓某一个程序不想抓全局流量。可以关闭Fiddler的系统代理然后手动把目标程序的代理指向127.0.0.1:8888。命令行工具可以设置HTTP_PROXY和HTTPS_PROXY环境变量Java程序可以加JVM参数指定代理这样流量就只走Fiddler。抓取Windows服务或者后台进程的流量。很多系统服务走的是WinHTTP而不是WinINETFiddler默认只改WinINET代理这时候你会发现服务流量没进Fiddler。这种场景需要单独配置WinHTTP代理或用Fiddler的命令行工具处理。环境准备是抓包的基础也是很多新手最容易卡住的地方。配置好以后Fiddler会话列表里就能看到大量的HTTPS明文请求了接下来才能真正开始排查问题。3. 抓包实战完整走查一个请求3.1 从开发者工具到Fiddler的定位流程实际排查问题时我的第一入口永远是开发者工具。先在Network面板里找到可疑请求看它的状态码、耗时、请求参数然后复制出完整URL到Fiddler里用快捷键CtrlF搜索这个URL。这样做的好处是开发者工具能告诉你这个请求是在哪个页面、由哪段脚本触发的Fiddler则告诉你这个请求完整的链路信息。两边对照很快就能缩小问题范围。举个例子。某天同事反馈一个下载接口点击后迟迟不弹下载框开发者工具里看到的请求只有一条最终状态200。我打开Fiddler重新操作了一遍发现点击按钮其实引发了两次HTTP请求第一次302跳到一个临时下载地址第二次才真正返回文件。开发者工具里因为自动跟随了重定向看起来好像只有一次请求而Fiddler里两个会话列得清清楚楚。这种重定向场景光靠浏览器面板很容易漏掉中间步骤看起来越是“正常”的200越可能在链路中间发生了额外跳转。还有其他场景也很适合从Fiddler入手定位请求发送内容和代码里不一致。前端说提交的是完整JSON后端说收到的是截断数据。Fiddler里可以看原始请求字节一眼看出是哪里被改了。响应内容感觉像被缓存。Fiddler会话里看响应头和实际内容配合源服务器对比能判断是代理缓存还是浏览器缓存。请求耗时波动大。Fiddler的Stats页签会拆分DNS解析、TCP连接、发送、等待、接收这几个阶段比开发者工具的水瀑布更细化一些。3.2 Inspectors解剖请求和响应的原始结构在Fiddler会话列表里选中一条请求右侧Inspectors区域会展示这条请求的详细内容。上面是请求下面是响应。Headers页签可以看所有请求头和响应头。很多时候接口的坑不在参数而在Header。比如服务端根据Accept-Encoding决定返回压缩还是原文根据Cookie判断登录态根据Referer做防盗链。遇到这类问题我在Fiddler里先看请求头再和服务端要求的字段比对比在代码里Debug更直接。TextView页签可以看纯文本响应体。如果响应是JSON但格式混乱这里也能看到原始样子。遇到返回内容是二进制、协议缓冲区或者图片HexView页签才是准确的查看方式。还有一个细节WebForms页签会把POST请求的表单体解析成键值对展示。但它只适合application/x-www-form-urlencoded如果是JSON格式的body要看Raw或者JSON页签。我个人看响应头时比较关注几个字段Content-Type确认返回到底是JSON还是纯文本经常有后端返回了text/html前端拿JSON.parse解析导致报错。Cache-Control和Expires观察接口是否被强制缓存。Set-Cookie这个响应改了哪些Cookie很多时候登录态丢失和它有关。Location配合状态码判断重定向目标。3.3 断点修改向前和向后的拦截Fiddler最好用的功能之一就是断点。它不需要在代码里打日志也不需要改代码重新编译直接在请求发出前或响应返回前暂停让你改完再继续。设置方式很简单菜单栏Rules Automatic Breakpoints Before Requests这样所有请求在发出前都会被拦截。也可以只针对某一条请求右键会话选择Set Breakpoint。请求被拦截后Fiddler底部会出现一个Breakpoints面板你可以在这里改URL、改请求头、改请求体。改完之后点击Run to Completion请求才会真正发出去。After Responses则对应响应返回后、交还给客户端前。比如后端返回一个状态码500的JSON我想模拟成200就在响应拦截时把状态码改成200响应体也一起改掉。这样不需要后端配合前端就可以先拿着模拟数据继续开发。这里有个实用习惯断点修改最好配合会话右键菜单里的“Unlock”使用因为Fiddler默认锁定了只读状态的会话。右键点击会话选择Unlock或者直接按F7就能自由编辑了。有一次我排查一个登录态问题用户登录之后调接口仍然返回未登录。我用断点把请求拦截下来带上正确的Cookie重放这个接口发现问题还在说明后端根本没看Cookie而是从另一个Header取用户身份。这种排查思路比在代码里上下翻找要快得多。3.4 Replay和Composer重放与构造请求排查完一个请求想验证修改后的效果可以直接右键会话选择ReplayFiddler会用原请求重新发一遍。也可以按住Ctrl选择多条会话批量重放适合压测几个接口。Replay用的是原请求的所有信息。但要注意某些接口的请求头里有时间戳或者防重复参数原样重放可能直接被后端拒绝。这种场景建议用Composer把会话拖到Composer页签先编辑参数再发送。Composer相当于一个手工构造HTTP请求的工具可以自己填Method、URL、Headers、Body适合做各种边界测试。我在构造请求时比较注意以下几点去掉不确定的Header。比如Content-LengthFiddler往往会在发送前自动计算手写反而容易出错。检查Cookie。如果Cookie过期了重放结果可能和浏览器里完全不一样。如果是POST请求确认Content-Type和Body格式匹配。Fiddler不会帮你转义JSON格式错了服务端会直接报错。4. 进阶实战移动端抓包和规则自动化4.1 手机流量怎么进Fiddler移动端App调试比浏览器麻烦一点但Fiddler处理起来也成熟。手机抓包和电脑抓包本质一样都是让手机流量走Fiddler这个代理。步骤大概是确认电脑和手机在同一个局域网。Fiddler里打开Tools Options Connections勾选Allow remote computers to connect。查看电脑的局域网IP比如192.168.x.x。手机Wi-Fi设置里手动配置HTTP代理服务器填电脑IP端口8888。手机浏览器访问http://电脑IP:8888进入Fiddler的证书下载页点击FiddlerRoot certificate下载并安装证书。iOS设备安装完证书后还要去“设置 通用 关于本机 证书信任设置”把Fiddler证书手动打开信任开关否则即使装了也白搭。Android平台相对麻烦一些7.0及以上版本默认不信任用户安装的CA证书所以很多App的HTTPS请求在装了Fiddler证书后仍然会报SSL错误。如果遇到App做了SSL Pinning也就是把服务端证书固定死在App内部那Fiddler的根证书是不可能被信任的。这种情况不建议去破解App的证书校验正确做法是找App开发方提供一个关闭了证书校验的测试包或者在一个开了系统信任用户证书的调试环境里测。移动端抓包时经常遇到一个现象Fiddler会话列表里能看到很多来自手机系统的后台请求和你要调试的App无关。建议先用Fiddler的过滤器按Host过滤只保留目标服务器的域名不然会话一多很难看。4.2 AutoResponder不依赖后端造数据前端开发经常遇到“后端接口还没写好但前端想先联调”的局面。Fiddler的AutoResponder就是为这种场景准备的。它做的事很简单当某个请求命中你设置的规则时Fiddler直接返回你指定的内容不会再真正发给服务器。我的用法是先在Fiddler里抓到目标接口的请求。右键这个会话选择Add Rule它会自动填入匹配条件。在Rule Editor里把响应设置成本地文件路径或者一段字符串。勾选Enable rules重新触发前端页面操作。匹配规则支持正则表达式。比如我想把所有请求example.com/api/user开头的接口都指到本地mock数据可以写regex:.*example\.com/api/user.*然后响应指向一个本地JSON文件。注意文件路径最好用纯英文有些环境对中文路径支持不好。AutoResponder最值钱的用法是模拟异常响应。比如后端某个接口返回了500前端已经上线了我想测试前端对500的处理是否正常就让AutoResponder拦截这个请求直接返回一段500的响应体。这样既不影响线上数据又能验证错误逻辑。还需要注意规则优先级Fiddler是从上到下逐条匹配的排在上面的规则先生效。多规则并存时建议把特殊规则放上面兜底规则放下面。4.3 Fiddler脚本给日常工作加一点自动化Fiddler还有一个被忽视的扩展能力FiddlerScript。通过菜单Rules Customize Rules可以打开脚本编辑器里面用类C#的语法写逻辑可以在每个请求和每个响应经过时执行自定义代码。最早我是被海量会话搞得烦躁后来在OnBeforeRequest里加了点逻辑几十个域名统一标记不同颜色根据状态码自动备注排查效率高了很多。比如想给某个接口的响应自动加一个Header可以这样写static function OnBeforeResponse(oSession: Session) { if (oSession.HostnameIs(www.example.com) oSession.uriContains(/api/user)) { oSession.oResponse[X-Fiddler-Debug] mock-response; } }想在请求发出前修改参数也可以static function OnBeforeRequest(oSession: Session) { if (oSession.uriContains(/api/login)) { oSession.oRequest[X-Env] test; } }脚本适合做重复性工作比如批量替换环境域名、给线上接口自动加测试标记、统计某类请求的数量。但脚本逻辑写复杂以后不好调试我的建议是先用AutoResponder和断点解决只有确认需要批量处理时再上脚本不要一开始就想着搞自动化压测。5. 和开发者工具配合时的实战习惯5.1 一套实用的双端对照排查节奏这几年用下来我整理了一套固定流程遇到接口问题基本按这个节奏走先在开发者工具Network里找到目标请求确认状态码、耗时、请求参数并查看Initiator列的调用栈定位是哪段代码发出的请求。如果开发者工具信息不够再打开Fiddler清空会话复现操作找到对应会话。在Fiddler里看请求和响应的原始内容对比开发者工具面板里的展示结果判断差异出现在哪一环。如果怀疑是前端处理问题用断点修改响应模拟各种边界情况观察前端表现。如果怀疑是后端问题用Composer直接修改参数重放请求和后端日志对照。这套流程最核心的一步是第3步。很多“前端说后端有问题后端说前端有问题”的争论最后在Fiddler里都能得到明确结论因为这里看到的是数据最原始的样子。举个例子有一次接口报错前端从开发者工具里看响应Message是一段中文但页面弹窗显示乱码。打开Fiddler看原始响应发现Content-Type是application/json但实际返回的body是GBK编码。开发者工具自动按UTF-8解码了所以看是正常的Fiddler里却能发现编码标记和实际内容不一致。这种底层问题没有中间层视角很难定位。5.2 Fiddler的常见问题再补充最后把使用过程中容易踩的问题集中说一下会话列表全是红色。这基本是HTTPS证书校验失败。重新安装信任根证书检查系统时间然后重启浏览器。抓不到某些进程的流量。先确认这个进程是否走系统代理。很多命令行工具默认不走代理需要手动设置环境变量。开着Fiddler网速变慢。这是正常现象因为它接管了所有代理流量。会话多了以后可以右键会话选择Remove减少列表压力。也可以通过菜单Tools Options Gateway把不需要的地址加入绕过列表。页面提示无法连接代理。大概率是Fiddler监听的端口被其他程序占用了换一个端口或者在Fiddler里改端口后同步更新客户端代理配置。手机通过代理访问很慢。优先确认是不是AP隔离了设备间通信如果路由器开启了AP隔离手机和电脑之间是不允许互相通信的。移动端抓包我还有一个习惯只开需要调试的那一个应用把其他App的联网全部停掉。要不然Fiddler塞满了各种App的请求真正想看的那个反而被淹没。5.3 我的固定操作习惯现在每次调试HTTP接口我基本都是Fiddler常开浏览器开发者工具也常开两个窗口并排放。F12负责定位前端脚本调用的上下文Fiddler负责看清链路真实数据。看起来好像多了一道工具实际上大部分接口问题的排查时间都因为这道工具减少了很多。最后分享一下我的固定动作抓包前先看一眼Fiddler左下角是不是显示“Capturing”没有的话按F12开启抓完后点一次过滤按钮把无关会话藏起来改完响应再确认一下AutoResponder规则是否关闭不然下一次请求还会被拦截导致“怎么莫名其妙拿到旧数据”的假象。这些细节一次记住后面就顺畅了。