使用Fiddler抓包的时候,自动化、定制化的保存请求数据或响应数据是一个高频且刚需的需求。
实现过程
- 编写js脚本
- 获取响应数据
- 保存数据或处理数据
设置脚本
Fiddler支持 自定义脚本来实现该功能,默认支持js脚本。
选择:Rules->Customize Rules..(规则-> 自定义规则)
也可以直接使用快捷键 Ctrl+R
这时会自动使用默认的文本编辑器打开Rules脚本文件。一般是Windows系统自带的txt软件,也可以自定义指定,我这里指定使用vscode软件。
设置过程如下:

这里就可以随意修改,增加你的自定义规则了。
脚本代码就是js语言。
保存Response
比如我这里做的:我抖音里关注了一千多个作者,设置fiddler抓包后,发现返回的是分页的json数据,我想让fiddler自动把这些json保存到磁盘文件。
修改脚本,找到 OnBeforeResponse 方法修改即可,修改后可能需要重启。
static function OnBeforeResponse(oSession) {if (m_Hide304s && oSession.responseCode == 304) {oSession["ui-hide"] = "true";}//过滤:抖音关注接口if (oSession.fullUrl.Contains("https://api3-normal-c-lq.amemv.com/aweme/v1/user/following/list")){// 保存文件到本地var fso;var file;fso = new ActiveXObject("Scripting.FileSystemObject");// ActiveXObject.OpenTextFile()方法 必须是目录存在,需要提前建立文件目录file = fso.OpenTextFile("D:\\FiddlerData\\Sessions.txt",8 ,true, true);// oSession.GetResponseBodyAsString() 为获取相应的json数据file.writeLine(oSession.GetResponseBodyAsString());file.writeLine("\n");file.close();}}
抓取到数据如下:
记录下其他代码,方便拷贝:
保存数据并且发送给自己的某服务示例
static function OnBeforeResponse(oSession: Session) {if (m_Hide304s && oSession.responseCode == 304) {oSession["ui-hide"] = "true";}// if (oSession.fullUrl.Contains("baidu.com")){if (1){oSession.utilDecodeResponse();//消除保存的请求可能存在乱码的情况var jsonString = oSession.GetResponseBodyAsString();var responseJSON = Fiddler.WebFormats.JSON.JsonDecode(jsonString);if((responseJSON.JSONObject=='System.Collections.ArrayList' || responseJSON.JSONObject=='System.Collections.Hashtable')&&jsonString!='[]'&&jsonString!='{}'){// 判断是否是json数据 然后保存var str='{}';//构造自己的JSON http请求的信息及返回的结果var data = Fiddler.WebFormats.JSON.JsonDecode(str);data.JSONObject["request_method"] = oSession.RequestMethod;var requestString = oSession.GetRequestBodyAsString();data.JSONObject["request_body"]= requestString;data.JSONObject["response_data"] = responseJSON.JSONObject;data.JSONObject["url"] = oSession.fullUrl;data.JSONObject["response_code"] = oSession.responseCode;jsonString = Fiddler.WebFormats.JSON.JsonEncode(data.JSONObject)// 保存文件到本地var fso;var file;fso = new ActiveXObject("Scripting.FileSystemObject");file = fso.OpenTextFile("E:\\spider_img\\Sessions.dat",8 ,true, true);file.writeLine(jsonString);file.writeLine("\n");file.close();// 数据通过post请求发送自己的后台服务保存FiddlerObject.log('2222222222222222'+jsonString);// methodsvar method = "POST";var myUrl = 'http://localhost:8000/fiddler'var url = myUrl+'?data='+Utilities.UrlEncode(jsonString);var protocol = "HTTP/1.1";var raw="";var selected: Session = oSession;raw += method + " " + url + " " + protocol + "\r\n";raw +="Host:localhost:8000\r\n";raw +="Connection: keep-alive\r\n";raw +="Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n";raw +="User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36\r\n";raw +="Accept-Encoding: gzip,deflate,sdch\r\n";raw +="Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4\r\n";raw +="Content-Type: application/json\r\n";var body= "jsondata=''";raw += "\r\n" + body;FiddlerObject.utilIssueRequest(raw);}}}
保存图片示例
static function OnDone(oSession: Session) {//检查Content-Typeif (oSession.ResponseHeaders["Content-Type"]!=null || oSession.ResponseHeaders["content-type"]!=null){//避免不规范标头var contentType=oSession.ResponseHeaders["Content-Type"];if (String.IsNullOrEmpty(contentType) )contentType=oSession.ResponseHeaders["content-type"];//判定请求是否图片if (contentType.Contains("image")){//确定文件名(保存用)var fileName="";var fileIndex = oSession.RequestHeaders.RequestPath.LastIndexOf ("/");if (fileIndex>0)fileName = oSession.RequestHeaders.RequestPath.Substring (fileIndex+1);//如果文件名非法(名称含非法字符)if(fileName.IndexOf('?')>0 || fileName.IndexOf('&') )fileName=String.Empty;//输出日志(在Fiddler 主窗口,日志处输出)//FiddlerObject.log("Content-Type:"+ contentType +" RequestPath:"+oSession.RequestHeaders.RequestPath);//如果文件名为Null,自行创建一个文件名(Guid)if (String.IsNullOrEmpty( fileName)){fileName=Guid.NewGuid().ToString();var extName= contentType.Replace("image/","");fileName=fileName+"."+extName;}//太小的图片不要,比如站位图片(自行调节)if (oSession.ResponseBody.Length>100){//指定保存位置var saveDir="d:\\Temp\\";//不存在则创建文件夹if (!System.IO.Directory.Exists(saveDir))System.IO.Directory.CreateDirectory(saveDir);//保存响应流oSession.SaveResponseBody(saveDir+fileName);//写日志FiddlerObject.log("[文件保存]:"+fileName)}}}}
保存Request
理,也可以修改Request,把下面代码贴在OnBeforeRequest()方法末尾
//过滤无关请求,只关注特定请求if (oSession.fullUrl.Contains("szhome.com")){var fso;var file;fso = new ActiveXObject("Scripting.FileSystemObject");//文件保存路径,可自定义file = fso.OpenTextFile("D:\\Fiddler Sessions\\Sessions.txt",8 ,true, true);file.writeLine("Request url: " + oSession.url);file.writeLine("Request header:" + "\n" + oSession.oRequest.headers);file.writeLine("Request body: " + oSession.GetRequestBodyAsString());file.writeLine("\n");file.close();}
FiddlerScript 中的主要方法
你的FiddlerScript 文件中包含一个静态类Handlers,一般来说,你的代码应该写在这个类的静态方法中。
Fiddler 运行时会自动执行一些” Application event methods”:
| static function OnBoot | fiddler 启动时调用 |
|---|---|
| static function OnShutdown | fiddler关闭时调用 |
| static function OnAttach | fiddler注册成系统代理时调用 |
| static function OnDetach | fiddler 取消注册系统代理时调用 |
| static function Main | 在每次fiddler启动时和编译CustomRules.js 脚本时调用。 |
// 在这个方法中修改Request的内容, 我们用得最多
static function OnBeforeRequest(oSession: Session)
// 在这个方法中修改Response的内容
static function OnBeforeResponse(oSession: Session)
// 在个方法中包含Fiddler 命令,在Fiddler界面中左下方的QuickExec Box,如果你的脚本处理了指定的命令,则返回true,否则返回false.
static function OnExecAction(sParams: String[])
参考资料
- JScript.NET语言参考:http://msdn.microsoft.com/en-us/library/z688wt03(VS.80).aspx
- 控制Session 的UI样式:http://www.fiddlerbook.com/Fiddler/dev/SessionFlags.asp
- Fiddler Script 的官方帮助文档:http://www.fiddlerbook.com/Fiddler/dev/ScriptSamples.asp
- 修改Fiddler 请求与响应:http://fiddler2.com/documentation/KnowledgeBase/FiddlerScript/ModifyRequestOrResponse
- Fiddler Blog: http://www.telerik.com/automated-testing-tools/blog/eric-lawrence.aspx
