做接口测试和性能测试的朋友,应该都体会过这种痛:接手一个老系统,接口文档残缺不全,只能靠抓包工具去还原真实请求;等把URL、Header、Body一个个理清楚,再跑到JMeter里手工添加HTTP请求,复制粘贴几十次,半天就没了。尤其遇到那种几十个接口、参数还特别多的项目,光是整理请求就能把人逼疯。后来我试了试用Fiddler抓包后通过插件直接导出JMeter脚本,原本一天的活,十分钟就能搞定。这篇文章就把这个插件的原理和基本用法完整拆一遍,包括为什么会失效、哪些坑不能踩、导出的脚本该怎么二次加工,全部讲透。
1. 为什么要做请求脚本的自动转换
1.1 手工整理接口用例有多吃亏
很多测试同学的习惯是打开Jmeter,右键添加线程组,再往里面一个个加HTTP请求。这种做法在接口数量少、参数简单的时候没什么问题,但凡是真实业务系统,接口数量动辄几十上百,而且每个接口的Header里往往还带着Authorization、Referer、Content-Type之类的一堆字段。
我第一次在一个老项目里做性能测试时,光是整理登录、列表、详情、提交订单这几条业务链路的请求,就花了大半天。中间还踩了不少暗坑:比如请求头里有个字段只在特定页面才会带上,手工整理时很容易漏掉;又比如某个POST接口的请求体是嵌套JSON,手抖少了一个括号,接口直接返回400。这种错误很难发现,排查起来更费劲。相比之下,用Fiddler抓包获取到的请求是真实流量,什么字段都不缺,什么参数都够全,直接把会话转成脚本,是最不容易出错的方式。
1.2 主流的三种“抓包转脚本”路径
把抓包请求转成JMeter脚本,目前业界主要走三条路,我分别是都试过,先说结论:
| 方案 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|
| JMeter自带HTTP代理服务器录制 | 不需要额外工具,直接在JMeter里录 | 录制过程会产生大量无关流量,且对复杂请求支持较弱 | 快速搭一个简单的脚本原型 |
| 抓包工具导出HAR再用转换工具 | 通用性强,HAR是标准格式,很多工具支持 | 中间多一步转换,HAR转换时需要二次清理 | 团队内部没有明确统一的脚本生成工具时 |
| Fiddler插件直接导出JMeter脚本 | 操作链路短,Fiddler里过滤完会话直接导出,生成的结构贴近JMeter习惯 | 需要先熟悉插件配置,不同版本兼容性有差异 | 日常接口抓包与测试都依赖Fiddler的团队 |
我自己日常用得最多的是第三种,因为我在Windows环境下做抓包分析基本都用Fiddler,会话整理好之后顺手就导出了,不用再开一个工具去转格式。不过要注意,插件不是万能的,后面我会讲它到底能解决什么问题、不能解决什么问题。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 插件的工作原理:Fiddler的Session数据怎么变成JMX
2.1 Fiddler眼中的请求会话
要理解这个插件,先得搞清楚Fiddler是怎么存请求数据的。Fiddler启动后会注册系统代理,所有经过代理的HTTP/HTTPS请求都会被抓到,每个请求对应一个Session对象。这个Session对象里保存了完整的请求信息:请求方法、URL、协议版本、请求头集合、请求体、响应头、响应体、消耗时间、客户端IP等。
举个例子,你登录一个网页时浏览器发了一个POST请求:
text复制POST https://api.example.com/api/login HTTP/1.1
Host: api.example.com
Content-Type: application/json
User-Agent: Mozilla/5.0 ...
Authorization: Bearer xxxxx
{"username":"test","password":"123456"}
在Fiddler的会话列表里,这一整条记录就是一条Session。插件做的事,说穿了就是遍历你选中的这些Session,把里面记录的Method、URL、Headers、Body等信息取出来,再按照JMeter能识别的格式重新组装成一个.jmx文件。
2.2 从HTTP请求到JMeter Sampler的映射关系
JMeter的脚本本质上是一个JMX格式的XML文件,里面定义了TestPlan、ThreadGroup、Sampler、Listener等层级结构。插件需要把Fiddler的Session字段映射到JMeter的组件属性上。
我整理了一张常用的映射关系表:
| Fiddler字段 | JMeter对应位置 | 说明 |
|---|---|---|
| RequestHeaders 中的 Host、URL | HTTPSamplerProxy 的 protocol、domain、port、path | 决定请求发到哪 |
| Session.RequestMethod | HTTPSamplerProxy 的 method | GET/POST/PUT/DELETE等 |
| RequestHeaders 中除Host外的字段 | HeaderManager 中的 Header 列表 | 比如 User-Agent、Referer、Content-Type |
| RequestHeaders 中的 Cookie | CookieManager 或 HeaderManager | 有的插件会单独生成Cookie管理器 |
| RequestBody | HTTPSamplerProxy 的 Body Data 或 参数列表 | 表单格式会拆成参数,JSON格式保留为Body |
| 响应数据 | 插件可在Sample中预置断言 | 有的插件允许生成简单的响应断言 |
从整体结构上看,插件生成的JMX文件一般长这样:
text复制jmeterTestPlan
hashTree
TestPlan
hashTree
ThreadGroup
hashTree
HTTPSamplerProxy // 第一个接口
hashTree
HeaderManager
hashTree
HTTPSamplerProxy // 第二个接口
hashTree
HeaderManager
hashTree
这个结构的顺序和JMeter里手工添加组件的顺序是对应的。插件把Fiddler里选中的Session按时间顺序排列,生成一组顺序执行的HTTPSamplerProxy,每个Sampler下面挂着对应的HeaderManager。所以你拿到导出的脚本后,看到的请求顺序基本就是你抓包时的操作顺序。
2.3 过滤规则为什么是导出前必做的一步
这里要特别提醒一个工具使用原则:Fiddler默认会抓到所有经过代理的流量,包括JS文件、CSS、图片、埋点请求、第三方统计接口,有的网页还会请求一堆广告域名。如果你不做任何过滤,直接把全部会话导出,生成的脚本会非常臃肿——里面充斥着大量没用的静态资源请求,JMeter跑起来耗资源,脚本可读性也差。
所以插件一般都会让你先选中要导出的Session,或者提供域名过滤条件。这一步不是可选项,而是导出前必须做的事。我习惯的做法是:先按目标域名筛选,比如只保留接口所在域名下的请求,再把静态资源类型排除掉,最后手动检查一遍会话列表,确认没有明显无关的请求后再导出。这样可以省掉很多导出后的清理时间。
3. 插件的基本使用:从抓包到生成JMeter脚本全流程
3.1 环境准备:Fiddler、JMeter与插件安装
在开始前,先把环境准备好。
第一,安装Fiddler Classic。这是免费版,功能对于日常抓包和脚本导出完全够用。装完后打开Tools -> Options,确认HTTPS选项卡里勾选了Decrypt HTTPS traffic。如果不开启HTTPS解密,你抓到的HTTPS请求只是一个CONNECT隧道,根本看不到具体请求头和请求体,导出的脚本自然也是废的。
第二,安装JMeter。JMeter是纯Java应用,需要JDK或JRE环境。下载解压后,在bin目录下执行jmeter.bat(Windows环境)启动,能看到JMeter图形界面就算装好了。
第三,安装导出插件。Fiddler的插件安装方式不算统一,有的提供安装包,有的是把dll文件放到Fiddler的Scripts目录下。常见的做法是从Fiddler菜单栏的Tools -> Extension Manager里查看已装的插件,如果插件自带安装程序,运行后重启Fiddler就能看到新菜单项出现。安装完成后,在Fiddler的Session列表上右键,如果菜单里出现了类似Export to JMeter或Generate JMeter Script的选项,说明插件加载成功了。
3.2 抓包前置配置
环境准备好之后,先不要急着抓包,花几分钟把代理配好。
Fiddler启动后会自动设置系统代理,默认监听地址是127.0.0.1:8888。在电脑上抓包,浏览器直接就能被抓到;但如果你要抓手机上的请求,就需要在手机WiFi设置里手动配置HTTP代理,把代理服务器地址指向电脑的局域网IP,端口填8888。同时手机还需要安装Fiddler的根证书,否则HTTPS请求解密不了。
在抓包之前,建议先清空Fiddler的会话列表,或者开启一个自动过滤规则。这样你执行一轮业务操作后,留下的会话比较干净,不会混入之前的历史请求。然后按正常的用户路径操作一遍系统,比如登录、查询、提交数据。操作结束后,Fiddler列表里就保存了完整的请求记录了。
顺带提一句,如果抓的是移动端App的请求,要注意App是否做了证书校验。部分App会校验客户端证书,导致Fiddler的HTTPS解密失败,这时候需要App端配合开启允许用户证书,或者用其他抓包方案。这个不是本篇重点,但遇到抓不到包时先往这个方向排查。
3.3 筛选Session并导出脚本
抓完包之后,Session列表里会有几十甚至上百条记录。接下来按我之前说的思路过滤:
- 在Filters选项卡里设置Host过滤,只保留目标域名下的请求;
- 如果有静态资源请求,可以按Content-Type或文件后缀过滤掉js、css、png这类请求;
- 手工检查会话列表,把明显无关的请求(比如广告、埋点)右键Remove掉。
确认Session列表里只剩你要的业务接口后,全选这些Session,右键找到插件提供的导出入口。点击后,一般会弹出一个配置窗口,需要设置几项内容:
- 线程组名称和并发数(导出的脚本默认只有一个线程组,可以先设成单线程)
- 是否包含请求头,是否生成HeaderManager
- 是否包含Cookie,是否生成CookieManager
- 是否生成断言(有的插件支持为每个Sampler加一个响应断言)
- 保存的JMX文件路径
配置完点确认,插件就会生成一个.jmx文件。这个文件可以直接用JMeter打开。
3.4 在JMeter中验证导出的脚本
导出的脚本不是拿来就能跑,一定要先在JMeter里打开检查一遍。
我用JMeter打开生成的文件后,第一步先看TestPlan树的整体结构,确认线程组和Sampler都正确挂载。第二步看每个Sampler的配置,重点检查请求方法、URL、Header和Body数据是否和Fiddler里一致。第三步是添加一个View Results Tree监听器,运行一次,观察请求是否返回200,响应内容是否符合预期。
如果你导出的请求里有动态字段,比如登录接口返回的token被下一个接口用在了Header中,那脚本首跑大概率会失败,因为录制当时的值已经失效了。这种问题不用慌,属于正常现象,后面我会讲怎么处理。
验证脚本的过程中,推荐用JMeter的调试功能:添加一个Debug Sampler和View Results Tree,查看JMeter发出去的请求实际长什么样。如果发现发出去的请求头顺序、字段值跟Fiddler里不一致,可以再回头调整。
3.5 一个登录+业务请求的小案例
为了更直观,我模拟一个常见场景:登录接口返回token,再用token查询订单列表。
在Fiddler里抓到的两条请求大概是这样的:
text复制POST https://api.example.com/api/login
Header: Content-Type: application/json
Body: {"username":"test","password":"abc123"}
GET https://api.example.com/api/order/list?page=1
Header: Authorization: Bearer eyJhbGciOi...
用插件导出后,JMeter里会生成两个HTTPSamplerProxy。第一个Sampler发送登录请求,BodyData保留完整的JSON;第二个Sampler是GET请求,QueryString里带page=1,HeaderManager里带了Authorization。
但这里有个问题:第二个请求的Authorization是录制时从服务端返回的,已经过期。要让脚本能重复跑,需要在登录请求下面加一个JSON Extractor,从返回值里提取token字段,再在第二个请求的HeaderManager里用${token}变量引用。这一步是必须的人工加工,任何抓包工具和插件都代替不了。后面第4部分我会详细说这类动态参数的处理方法。
4. 常见问题排查:为什么导出的脚本总是跑不通
4.1 抓包正常但导出的脚本请求失败
这个现象最常见,也最容易误判。如果你发现Fiddler里请求都正常,但JMeter里跑同样的请求就失败,大概率是HTTPS证书校验导致的。JMeter运行脚本时,如果目标接口证书是自签名证书,或JMeter所在机器的JDK证书库没有信任该证书,就会报SSL握手失败。
解决方案有两个:一是把Fiddler导出的根证书导入到JMeter使用的JDK证书库中;二是在JMeter的HTTPSamplerProxy里禁用SSL证书验证,具体是在JMeter的system.properties里设置:
properties复制server.rmi.ssl.disable=true
或者更简单,在测试计划里添加一个HTTP请求默认值,把Implementation设置为HttpClient4,并勾选Use KeepAlive,某些SSL问题也能缓解。具体用哪种方式,取决于你的JMeter版本和目标服务器证书情况。
4.2 响应乱码或中文乱码
这种情况通常是请求头里的Accept-Encoding带了gzip,Fiddler会把响应自动解压后再展示,但JMeter默认不会自动解压,导致你看到的是乱码。
排查方法是:在JMeter里查看响应结果,如果是一堆无法阅读的字符,检查请求Header里的Accept-Encoding,把它删掉或改成identity。另外,如果接口返回的是UTF-8编码,但JMeter默认用的ISO-8859-1,也会出现中文乱码。可以在HTTP Request的Content Encoding里填UTF-8,或在jmeter.properties里修改sampleresult.default.encoding=UTF-8。
还有一个小坑:插件导出的HeaderManager里如果保留了Content-Length这个头,在JMeter里回放时会因为请求体变化导致长度不匹配,服务器可能直接断开连接。遇到这种情况,把Content-Length删掉就好。
4.3 需要登录态或动态Token该怎么办
这是抓包转脚本最常见的一个坎。录制的时候,Authorization、Cookie、签名参数都是当时的值,过一段时间就失效了。插件能做的是把参数原样保留,但它不知道这个参数是动态的,也不知道从哪里提取。
处理思路是:找到生成动态参数的接口,在JMeter里增加后置处理器。比如登录接口返回一个JSON,token字段在data.token,那就加一个JSON Extractor,填入表达式$.data.token,变量名设为token。然后在后续请求的HeaderManager里,把Authorization的值改成Bearer ${token}。如果需要签名的接口,还得用JSR223 Sampler写Groovy逻辑,从参数列表生成签名。这部分工作无法自动化,必须手工处理。
我见过不少人在这步卡住,觉得脚本录制工具不智能。其实这就是测试脚本从“能跑”到“能稳定跑”必须付出的代价。你只需要记住:动态参数是测试脚本的常态,提取器、正则、变量引用是基本功。
4.4 WebSocket或非HTTP请求导不出来
Fiddler插件通常只支持HTTP/HTTPS请求的转换。如果你抓到的请求里有WebSocket、TCP长连接、gRPC这类协议,插件一般无法生成对应的JMeter脚本。JMeter本身需要单独安装WebSocket插件才能支持这类协议。
遇到这种情况,我建议是单独开发脚本或使用专门的工具,不要指望抓包插件一把梭。比如WebSocket的请求,用JMeter的WebSocket Sampler手动构造消息;如果是gRPC,可以自己写客户端或配合其他工具。这个限制是由JMeter原生协议支持范围决定的,插件再强也突破不了底层框架的边界。
4.5 文件上传接口导出后无法使用
文件上传接口在Fiddler里看到的请求体是multipart/form-data格式,里面有个filename字段和一个二进制内容。插件导出时能保留表单结构,但文件内容本身没法直接写进JMeter脚本,JMeter的上传参数需要指定一个本地文件路径。
处理方法是:在JMeter的HTTP请求里找到上传对应的参数,把参数类型设为File,在文件名一栏填写上传文件的本地路径。如果文件是动态生成的,可以用__fileToString()函数或__P()属性来控制路径。这里需要注意,上传文件的路径最好用相对路径或通过JMeter变量传入,这样换台机器跑脚本时不用改脚本。
5. 进阶玩法与我的个人经验
5.1 导出后的脚本如何接入自动化回归
很多人把导出脚本停留在“能跑一次”的层面,其实把它接入自动化回归,价值更大。
我是这样做的:导出的脚本先手工处理后,用JMeter的命令行模式跑回归:
bash复制jmeter -n -t test-plan.jmx -l result.jtl -e -o report
-n代表非GUI模式,-l输出结果文件,-e生成HTML报告,-o指定报告输出目录。这条命令可以直接放进Jenkins或GitLab CI里,做成定时任务。每天晚上跑一次冒烟回归,接口挂了能第一时间发现。这样做的前提是脚本里的动态参数和断言都处理好了,不能每次跑都手工改东西。
所以插件只是帮你完成了“从抓包到脚本初稿”的最耗时部分,后面的参数化、断言、数据清理,才是脚本能否长期复用的关键。
5.2 HAR中间格式也是一个可靠的备选方案
如果有人用的Fiddler版本或插件在安装上遇到兼容性问题,也别死磕。Fiddler自带一个非常实用的导出功能——将Session导出为HAR格式(HTTP Archive),这是标准的HTTP流量记录格式。然后在JMeter里通过BlazeMeter的HAR Converter或在线转换工具,把HAR文件转成JMeter脚本。效果和插件导出类似,只是中间多了一步。
这个备选方案比较适合那些不方便装插件、或者公司内网环境受限的场合。我有时候快速验证一个需求,也会直接用HAR转换,因为不用额外安装东西,Fiddler装好就能导。
5.3 聊点实在话:自动转换不是终点
最后聊几句个人的感受。我觉得抓包转脚本这类工具,本质上解决的是“从0到1”的效率问题,也就是把重复的、机械的复制粘贴工作自动化。但从“1到100”,比如脚本的健壮性、可维护性、断言覆盖率,这些还是得靠人去打磨。
在实际项目中,我见过有人过度依赖录制工具,导出的脚本不检查就直接拿去压测,结果压的是一堆失效请求,数据全废。也有人因为插件导出的脚本第一次跑不通,就断定工具不好用,又退回手工一条条加请求的老路。这两种极端都不对。正确的是把插件当成“半自动”工具——让它生成一份准确的草稿,你再花两小时把动态参数、断言、关联关系处理好。这样用,效率提升是最明显的。
最后再分享一个小技巧:导出前,把Fiddler里无关的Session全部取消选中,只保留业务链路涉及的接口。这个动作看着简单,却能让你省掉导出后一小时的清理工作。脚本这东西,越干净越好维护。
