Fiddler抓包一键生成调用代码
首先我們的需求場景是
用Fiddler抓到某個接口調用后,用代碼來模擬調用,一般我們寫代碼會有3個步驟:
1設置http請求相關的參數:header,method,url,cookie等
2設置post的body(如果是post的話需要)
3拿到返回的body(一般我們需要拿到接口的返回體進行解析)
假如這3個步驟的代碼全部都能一鍵生成那該多爽,我終于站在巨人的肩膀上搞定了!
搞定的效果如下圖:
image上面是對于csharp 采用自帶的 HttpClient的代碼生成演示,還可以針對java kotlin,python,nodejs等
本篇的主要功能都是在FiddlerScript里面完成,主要包含3塊擴展
增加自定義右鍵菜單
增加控制開關
代碼獲取請求上下文并導出har
使用腳本完成process的封裝并調用
1. 增加右鍵菜單
點中某個Session然后點擊右鍵菜單,選擇生成指定語言的代碼,這樣使用起來最方便,如下圖:
新增右鍵菜單的擴展方式是 【一個ContextAction+一個function】
例如:
public?static?ContextAction("C#-httpclient",?"生成代碼")function?do1(arrSess:?Session[])?{??doStar(arrSess,?"csharp","httpclient");?}代表新增一個 一級菜單叫 生成代碼,二級菜單叫 "C#-httpclient"
下面的function就是點擊需要響應的方法實現,默認是Session數組,因為可以選擇多個。
2. 控制開關
前面說有3個步驟,除了第一個步驟是核心的,其他2個步驟都是將json轉為實體類定義,是輔助的。所以都設置開關可以人為控制要不要生成這2塊的代碼
如下圖:
image新增開關的方式是定義【一個RulesOption+一個對應接收的變量】
public?static?RulesOption("關閉請求體轉代碼",?"生成代碼")var?m_DisableReuqest:?boolean?=?false;代表新增一個 以及菜單叫生成代碼,二級菜單叫 "關閉請求體轉代碼",類型是bool,因為下面對應接收的變量是布爾類型!
3. 通過選中Session拿到整個請求的上下文
上下文包括,請求的各種參數,比如url,header,method,request,response等
imageFillder有一個api可以導出har文件,這個har格式是谷歌提出來的一個用來描述一個請求的標準定義,如上圖
關于har格式的詳細文檔:http://groups.google.com/group/http-archive-specification/
那如何在Fiddler里面將Session導出har呢
imageimageimage那用代碼如何導出呢?
//這種方式為導出到變量?注意是Fiddler?4.6.2.0版本之后支持的 var?oExportOptions?=?FiddlerObject.createDictionary();? oExportOptions.Add(“ExportToString”,?“true”); FiddlerApplication.DoExport("HTTPArchive?v1.2",?oSessions,oExportOptions,?null); //這個就是了 var?sOutput:?String?=?oExportOptions[“OutputAsString”];//這種方式為導出到指定路徑 var?oExportOptions?=?FiddlerObject.createDictionary();? oExportOptions.Add("Filename",?"對應的路徑");? FiddlerApplication.DoExport("HTTPArchive?v1.2",?oSessions,oExportOptions,?null);這里我采用了第二種方式,先把選中的Session導出一個har文件,然后將這個har文件作為下一個process的入參,得到我想要結果!
下面隆重介紹根據har來生成請求代碼的工具:httpsnippet
開源地址:https://github.com/Kong/httpsnippet
Kong的話有個很有有名的網關想必大家都聽說過!
這里我已經把這個程序包裝成在windows系統可以獨立運行的exe了,可以在文章末尾獲取下載鏈接。
這里我稍微改造了一下代碼,把har文件的requestBody和responseBody也提取出來,為了是生成對應的POJO代碼做入參.
將json生成實體類POJO這里用了另外一個工具:quicktype
開源地址:https://github.com/quicktype/quicktype
也包裝成在windows系統可以獨立運行的exe了。
好了,組裝一起:
先通過代碼生成har文件
然后用httpsnippet生成指定語言的代碼,并導出har中的requestBody和responseBody
分別將requestBody和responseBody作為參數讓quicktype生成實體類代碼
整個的完整代碼如下,按照如下步驟copy到fiddler的腳本編輯器中即可:
首先打開腳本編輯器:
image隨便找到一個空白的地方,然后把下面的代碼復制進去:
public?static?RulesOption("關閉請求體轉代碼",?"生成代碼")var?m_DisableReuqest:?boolean?=?false;public?static?RulesOption("關閉返回體轉代碼",?"生成代碼")var?m_DisableResponse:?boolean?=?false;public?static?ContextAction("C#-httpclient",?"生成代碼")function?do1(arrSess:?Session[])?{??doStar(arrSess,?"csharp","httpclient");?}public?static?ContextAction("C#-restsharp",?"生成代碼")function?do2(arrSess:?Session[])?{?doStar(arrSess,?"csharp","restsharp");?}public?static?ContextAction("Java-okhttp",?"生成代碼")function?do3(arrSess:?Session[])?{??doStar(arrSess,?"java","okhttp");?}public?static?ContextAction("Java-asynchttp",?"生成代碼")function?do4(arrSess:?Session[])?{??doStar(arrSess,?"java","asynchttp");?}public?static?ContextAction("Java-nethttp",?"生成代碼")function?do5(arrSess:?Session[])?{??doStar(arrSess,?"java","nethttp");?}public?static?ContextAction("Java-unirest",?"生成代碼")function?do6(arrSess:?Session[])?{??doStar(arrSess,?"java","unirest");?}public?static?ContextAction("Kotlin-okhttp",?"生成代碼")function?do7(arrSess:?Session[])?{??doStar(arrSess,?"kotlin","okhttp");?}public?static?ContextAction("JavaScript-xhr",?"生成代碼")function?do8(arrSess:?Session[])?{??doStar(arrSess,?"javascript","xhr");?}public?static?ContextAction("JavaScript-jquery",?"生成代碼")function?do9(arrSess:?Session[])?{??doStar(arrSess,?"javascript","jquery");?}public?static?ContextAction("JavaScript-fetch",?"生成代碼")function?do10(arrSess:?Session[])?{??doStar(arrSess,?"javascript","fetch");?}public?static?ContextAction("JavaScript-axios",?"生成代碼")function?do11(arrSess:?Session[])?{??doStar(arrSess,?"javascript","axios");?}public?static?ContextAction("Node-native",?"生成代碼")function?do12(arrSess:?Session[])?{??doStar(arrSess,?"node","native");?}public?static?ContextAction("Node-request",?"生成代碼")function?do13(arrSess:?Session[])?{??doStar(arrSess,?"node","request");?}public?static?ContextAction("Node-fetch",?"生成代碼")function?do14(arrSess:?Session[])?{??doStar(arrSess,?"node","fetch");?}public?static?ContextAction("Node-axios",?"生成代碼")function?do15(arrSess:?Session[])?{??doStar(arrSess,?"node","axios");?}???public?static?ContextAction("Node-unirest",?"生成代碼")function?do16(arrSess:?Session[])?{??doStar(arrSess,?"node","unirest");?}?public?static?ContextAction("Python3-http.client",?"生成代碼")function?do17(arrSess:?Session[])?{??doStar(arrSess,?"python","python3");?}public?static?ContextAction("Python-requests",?"生成代碼")function?do18(arrSess:?Session[])?{??doStar(arrSess,?"python","requests");?}public?static?ContextAction("ObjectiveC-nsurlsession",?"生成代碼")function?do19(arrSess:?Session[])?{??doStar(arrSess,?"objc","nsurlsession");?}public?static?ContextAction("Ruby-net::http",?"生成代碼")function?do20(arrSess:?Session[])?{??doStar(arrSess,?"ruby","native");?}public?static?ContextAction("Swift-nsurlsession",?"生成代碼")function?do21(arrSess:?Session[])?{??doStar(arrSess,?"swift","nsurlsession");?}public?static?ContextAction("powershell-webrequest",?"生成代碼")function?do22(arrSess:?Session[])?{??doStar(arrSess,?"powershell","webrequest");?}public?static?ContextAction("powershell-restmethod",?"生成代碼")function?do23(arrSess:?Session[])?{??doStar(arrSess,?"powershell","restmethod");?}public?static?ContextAction("Shell-curl",?"生成代碼")function?do24(arrSess:?Session[])?{??doStar(arrSess,?"shell","curl");?}public?static?ContextAction("Shell-httpie",?"生成代碼")function?do25(arrSess:?Session[])?{??doStar(arrSess,?"shell","httpie");?}public?static?ContextAction("Shell-wget",?"生成代碼")function?do26(arrSess:?Session[])?{??doStar(arrSess,?"shell","wget");?}public?static?ContextAction("Go-NewRequest",?"生成代碼")function?do27(arrSess:?Session[])?{?doStar(arrSess,?"go","native");?}public?static?ContextAction("Clojure-clj_http",?"生成代碼")function?do28(arrSess:?Session[])?{?doStar(arrSess,?"clojure","clj_http");?}public?static?ContextAction("C-Libcurl",?"生成代碼")function?do29(arrSess:?Session[])?{?doStar(arrSess,?"c","libcurl");?}public?static?ContextAction("PHP-curl",?"生成代碼")function?do30(arrSess:?Session[])?{??doStar(arrSess,?"php","curl");?}public?static?ContextAction("PHP-http1",?"生成代碼")function?do31(arrSess:?Session[])?{??doStar(arrSess,?"php","http1");?}public?static?ContextAction("PHP-http2",?"生成代碼")function?do32(arrSess:?Session[])?{??doStar(arrSess,?"php","http2");?}??public?static?function?doStar(oSessions:?Session[],?target:?String,client:String)?{//注意看這里,請下載我給的這2個exe并替換成你電腦中正確的目錄var?httpsnippet?=?"E:\\workspace\\github\\test\\httpsnippet.exe";var?quicktype?=?"E:\\workspace\\github\\test\\quicktype.exe";var?oExportOptions?=?FiddlerObject.createDictionary();?var?tempPath2?=?System.IO.Path.Combine(System.IO.Path.GetTempPath(),?"fiddler.har");if(System.IO.File.Exists(tempPath2)){System.IO.File.Delete(tempPath2);?}var?tempPath?=?System.IO.Path.Combine(System.IO.Path.GetTempPath(),?"fiddler.json");if(System.IO.File.Exists(tempPath)){System.IO.File.Delete(tempPath);?}var?tempRequestBodyPath?=?System.IO.Path.Combine(System.IO.Path.GetTempPath(),?"fiddler_requestBody.json");if(System.IO.File.Exists(tempRequestBodyPath)){System.IO.File.Delete(tempRequestBodyPath);?}var?tempResponseBodyPath?=?System.IO.Path.Combine(System.IO.Path.GetTempPath(),?"fiddler_responseBody.json");if(System.IO.File.Exists(tempResponseBodyPath)){System.IO.File.Delete(tempResponseBodyPath);?}oExportOptions.Add("Filename",?tempPath2);?FiddlerApplication.DoExport("HTTPArchive?v1.2",?oSessions,oExportOptions,?null);??System.IO.File.Move(tempPath2,?tempPath);if(!System.IO.File.Exists(tempPath)){MessageBox.Show("生成代碼失敗",?"No?action");return;??}var?rtPath?=?System.IO.Path.Combine(System.IO.Path.GetTempPath(),?"fiddler_rt");if(System.IO.Directory.Exists(rtPath))System.IO.Directory.Delete(rtPath,true);if(!doProcess(httpsnippet,?"\""+tempPath+"\"?-t?"+target+"?-c?"+client+"?-o?"?+?"\""+rtPath+"\"")){MessageBox.Show("生成代碼錯誤",?"No?action");return;??}var?file?=?System.IO.Directory.GetFiles(rtPath);if(file.Length!=1){MessageBox.Show("生成代碼錯誤",?"No?action");return;?}var?json?=?System.IO.File.ReadAllText(file[0]);System.IO.File.Delete(file[0]);var?rtPath1?=?System.IO.Path.Combine(System.IO.Path.GetTempPath(),?"fiddler_request_body");if(System.IO.File.Exists(rtPath1))System.IO.File.Delete(rtPath1);if(!m_DisableReuqest?&&?System.IO.File.Exists(tempRequestBodyPath)){json?+=?getJsonCode(quicktype,tempRequestBodyPath,rtPath,rtPath1,target,"FiddlerRequest");}rtPath1?=?System.IO.Path.Combine(System.IO.Path.GetTempPath(),?"fiddler_response_body");if(System.IO.File.Exists(rtPath1))System.IO.File.Delete(rtPath1);if(!m_DisableResponse?&&?System.IO.File.Exists(tempResponseBodyPath)){json?+=?getJsonCode(quicktype,tempResponseBodyPath,rtPath,rtPath1,target,?"FiddlerReponse");?}?Clipboard.SetText(json);MessageBox.Show("代碼生成成功,已復制到剪貼板");?}static?function?getJsonCode(file:?String,tempRequestBodyPath:String,rtPath:String,rtPath1:String,target:String,type:String):?String?{var?json?=?"";var?tmp1?=?"";if(target?==?'csharp'){tmp1?=?"--quiet?--telemetry?disable?--features?just-types?--array-type?list?--no-check-required?--namespace?\"Fiddlers\"?--lang?\""?+?target?+?"\"?--top-level?\""+type+"Model\"?\""?+?tempRequestBodyPath?+?"\""?+"?-o?"?+?"\""+rtPath1+"\"";}else?if(target?==?'kotlin'){tmp1?=?"--quiet?--telemetry?disable?--framework?just-types?--lang?\""?+?target?+?"\"?--top-level?\""+type+"Model\"?\""?+?tempRequestBodyPath?+?"\""?+"?-o?"?+?"\""+rtPath1+"\"";}else?if(target?==?'java'){tmp1?=?"--quiet?--telemetry?disable?--array-type?list?--just-types?--package?\"Fiddlers\"?--lang?\""?+?target?+?"\"?--top-level?\""+type+"Model\"?\""?+?tempRequestBodyPath?+?"\""?+"?-o?"?+?"\""+rtPath+"\\test"+"\"";}else?{tmp1?=?"--telemetry?disable?--just-types??--lang?\""?+?target?+?"\"?--top-level?\""+type+"Models\"?\""?+?tempRequestBodyPath?+?"\""?+"?-o?"?+?"\""+rtPath1+"\"";?}doProcess(file,?tmp1)if(System.IO.File.Exists(rtPath1)){json?+=?"\r\n//"+type+"-POJO\r\n"?+?System.IO.File.ReadAllText(rtPath1).Replace("package?quicktype","");}if(target?==?'java'){var?javaFiles?=?System.IO.Directory.GetFiles(rtPath,"*.java");?if(javaFiles.Length>0){json?+=?"\r\n//"+type+"-POJO\r\n"?;for?(var?i:int?=?0;?i<javaFiles.Length;?i++){json?+=?System.IO.File.ReadAllText(javaFiles[i]).Replace("package?Fiddlers;","")System.IO.File.Delete(javaFiles[i]);}}}return?json;}static?function?doProcess(file:?String,paramsList:String):?Boolean?{var?process?=?new?System.Diagnostics.Process();process.StartInfo.FileName?=?file;process.StartInfo.Arguments?=?paramsList;process.StartInfo.CreateNoWindow?=?true;process.StartInfo.WindowStyle?=?System.Diagnostics.ProcessWindowStyle.Hidden;process.StartInfo.UseShellExecute?=?false;process.StartInfo.Verb?=?"runas";process.StartInfo.RedirectStandardError?=?true;process.StartInfo.RedirectStandardOutput?=?true;process.Start();process.WaitForExit();process.Dispose();?return?true;}然后下載:httpsnippet和quicktype這2個可執行文件。獲取下載地址的方法:關注本公眾號后發送文本 :Fiddler ,會告訴你百度網盤鏈接!
下載zip包后然后把這2個文件解壓到你的電腦的某個目錄。
在回到腳本中找到 doStar 方法中修改成正確的目錄(別忘記了)
Enjoy!!!
其實在FiddlerScript里面還是能玩出很多花樣的,只不過寫擴展得用JScript.net(js+csharp的語法),什么語言不重要,重要的是實現了我想要的效果。
我是正東,學的越多不知道也越多。如果決定去深究一個東西, 一定要完全搞懂, 并認真總結一篇博客讓以后能在短時間拾起來 ( 因為不搞懂你很難寫一篇半年后還能理解的博客 )
總結
以上是生活随笔為你收集整理的Fiddler抓包一键生成调用代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .net core 中如何有效屏蔽重复提
- 下一篇: SignalR在React/Go技术栈的