Fiddler自动化抓包与数据持久化实战

张开发
2026/6/10 6:36:41 15 分钟阅读
Fiddler自动化抓包与数据持久化实战
1. Fiddler自动化抓包的核心价值当你需要长期监控某个App或网站的请求数据时手动一个个查看Fiddler的抓包结果简直是场噩梦。我去年负责一个电商项目的埋点测试每天要分析3000条请求数据直到发现FiddlerScript这个神器才真正解脱。通过脚本自动保存请求/响应数据不仅能实现7×24小时无人值守抓包还能直接生成结构化数据供后续分析。FiddlerScript本质上是用JScript.NET扩展Fiddler功能就像给普通汽车加装自动驾驶系统。最常用的两个入口点OnBeforeRequest请求发出前执行OnBeforeResponse响应返回前执行这两个时机相当于数据流水线的关键卡口比如我们在某金融App测试中通过下面这段代码实现了交易请求的自动存档static function OnBeforeRequest(oSession: Session) { if(oSession.uriContains(/api/v1/payment)) { var fso new ActiveXObject(Scripting.FileSystemObject); var file fso.OpenTextFile(C:\\PaymentLogs.txt, 8, true); file.WriteLine([ new Date() ] oSession.url); file.Close(); } }2. 文件操作API的实战细节2.1 文件写入的防坑指南新手最容易栽在文件路径和编码问题上。有次我脚本运行正常但文件始终为空折腾半天才发现是杀毒软件拦截了写入操作。这里分享几个关键参数的正确打开方式var file fso.OpenTextFile( D:\\Data\\log.txt, // 路径建议英文且不含空格 8, // 8表示追加写入模式 true, // 自动创建不存在的文件 -1 // -1代表UTF-8编码 );模式参数的秘密1 (ForReading)只读模式适合读取已有文件2 (ForWriting)覆盖写入会清空原内容8 (ForAppending)尾部追加日志记录首选2.2 多文件存储策略当需要按不同服务端接口分离数据时可以这样动态生成文件名static function OnBeforeResponse(oSession: Session) { var domain oSession.hostname; var path oSession.PathAndQuery.split(?)[0].replace(/\//g, _); var filename C:\\Logs\\ domain path .txt; var fso new ActiveXObject(Scripting.FileSystemObject); if(!fso.FileExists(filename)) { fso.CreateTextFile(filename); } var file fso.OpenTextFile(filename, 8, true, -1); file.WriteLine(oSession.GetResponseBodyAsString()); file.Close(); }这个方案在我们监控微服务架构时特别有用自动为每个API端点创建独立日志文件。记得添加异常处理有次磁盘写满导致脚本崩溃我们后来加了这样的保护try { // 文件操作代码 } catch(e) { oSession[ui-backcolor] red; oSession[ui-customcolumn] 写入失败: e.message; }3. 中文编码的终极解决方案3.1 编码问题现场还原某次测试中文用户名注册功能时保存的日志文件打开全是乱码。调试发现服务端用GBK编码而Fiddler默认用ASCII这就是典型的多系统编码不一致问题。最终解决方案是var file fso.OpenTextFile( user_log.txt, 8, true, -1 // -1代表UTF-8编码 );编码参数对照表参数值常量名编码格式-1TristateTrueUnicode(UTF-8)0TristateFalseASCII-2TristateDefault系统默认3.2 实时转码技巧遇到混合编码的数据流时可以先用GetResponseBodyAsString()获取原始数据再用.NET方法转码var rawData oSession.GetResponseBodyAsString(); var utf8Data System.Text.Encoding.Convert( System.Text.Encoding.GetEncoding(GB2312), System.Text.Encoding.UTF8, System.Text.Encoding.GetEncoding(GB2312).GetBytes(rawData) ); var file fso.OpenTextFile(data.txt, 2, true, -1); file.WriteLine(System.Text.Encoding.UTF8.GetString(utf8Data)); file.Close();4. 高级数据分割与处理4.1 URL参数智能解析分析电商搜索行为时我们需要从URL中提取关键参数。这段代码可以将查询参数转为JSON格式function parseQuery(url) { var query url.split(?)[1]; var params {}; query.split().forEach(function(pair) { var kv pair.split(); params[kv[0]] decodeURIComponent(kv[1] || ); }); return params; } static function OnBeforeRequest(oSession: Session) { if(oSession.uriContains(search?)) { var queryObj parseQuery(oSession.url); var logLine JSON.stringify({ timestamp: new Date(), keyword: queryObj.q, page: queryObj.pg || 1 }); saveToFile(search_log.json, logLine); } }4.2 请求体内容提取对于POST请求的JSON payload可以用这样的方式提取特定字段static function OnBeforeRequest(oSession: Session) { if(oSession.uriContains(/submit_order)) { try { var body oSession.GetRequestBodyAsString(); var orderData Fiddler.WebFormats.JSON.JsonDecode(body); saveToFile(orders.txt, 用户ID: orderData.JSONObject.userId \t 订单金额: orderData.JSONObject.amount ); } catch(e) { oSession[ui-errormsg] JSON解析失败; } } }5. 数据库持久化实战5.1 直接写入MySQL当需要实时分析数据时跳过文件直接入库更高效。这是我优化过的数据库写入方案function saveToMySQL(oSession) { var conn new ActiveXObject(ADODB.Connection); var strConn Driver{MySQL ODBC 8.0 Driver};Server127.0.0.1;Databaseapi_log;Userroot;Password123456;; try { conn.Open(strConn); var rs new ActiveXObject(ADODB.Recordset); var sql INSERT INTO request_log(method,url,status) VALUES(?,?,?); var cmd new ActiveXObject(ADODB.Command); cmd.ActiveConnection conn; cmd.CommandText sql; cmd.Parameters.Append(cmd.CreateParameter(method, 200, 1, 10, oSession.RequestMethod)); cmd.Parameters.Append(cmd.CreateParameter(url, 200, 1, 500, oSession.url)); cmd.Parameters.Append(cmd.CreateParameter(status, 3, 1, 0, oSession.responseCode)); cmd.Execute(); } finally { if(conn.State 1) conn.Close(); } }5.2 批量插入优化处理高并发请求时建议使用批量插入。我们通过临时文件定时导入的方式将写入性能提升了20倍var batchData []; static function OnBeforeResponse(oSession: Session) { batchData.push({ url: oSession.url, code: oSession.responseCode, time: new Date() }); if(batchData.length 100) { var tempFile C:\\Temp\\batch_ new Date().getTime() .json; saveToFile(tempFile, JSON.stringify(batchData)); batchData []; // 触发外部程序处理批量文件 var shell new ActiveXObject(WScript.Shell); shell.Run(C:\\Importer.exe tempFile, 0, false); } }6. 生产环境部署建议在正式环境使用时我强烈建议添加这些防护措施日志轮转- 每天自动创建新文件避免单个文件过大var logPrefix C:\\Logs\\api_ new Date().toISOString().split(T)[0]; var logFile logPrefix .log;敏感信息过滤- 自动脱敏身份证、银行卡等数据function maskSensitive(text) { return text.replace(/(\d{4})\d{10}(\d{4})/g, $1******$2) .replace(/([A-Za-z0-9._%-])([A-Za-z0-9.-]\.[A-Za-z]{2,})/g, ***$2); }性能监控- 记录脚本执行耗时避免影响主流程var startTime new Date().getTime(); // 处理逻辑... var elapsed new Date().getTime() - startTime; if(elapsed 1000) { FiddlerApplication.Log.LogString(警告处理耗时 elapsed ms); }实际项目中我们曾遇到脚本执行阻塞的问题后来通过添加超时机制解决var maxTime 5000; // 5秒超时 var start new Date().getTime(); while(processing) { if(new Date().getTime() - start maxTime) { throw 处理超时; } // 继续处理... }

更多文章