1. 程式人生 > 其它 >Fiddler抓包一鍵生成程式碼

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】

例如:


publicstaticContextAction("C#-httpclient","生成程式碼")
functiondo1(arrSess:Session[]){doStar(arrSess,"csharp","httpclient");}

代表新增一個 一級選單叫 生成程式碼,二級選單叫 "C#-httpclient"

下面的function就是點選需要響應的方法實現,預設是Session陣列,因為可以選擇多個。

2. 控制開關

前面說有3個步驟,除了第一個步驟是核心的,其他2個步驟都是將json轉為實體類定義,是輔助的。所以都設定開關可以人為控制要不要生成這2塊的程式碼

如下圖:

image

新增開關的方式是定義【一個RulesOption+一個對應接收的變數】

publicstaticRulesOption("關閉請求體轉程式碼","生成程式碼")
varm_DisableReuqest:boolean=false;

代表新增一個 以及選單叫生成程式碼,二級選單叫 "關閉請求體轉程式碼",型別是bool,因為下面對應接收的變數是布林型別!

3. 通過選中Session拿到整個請求的上下文

上下文包括,請求的各種引數,比如url,header,method,request,response等

image

Fillder有一個api可以匯出har檔案,這個har格式是谷歌提出來的一個用來描述一個請求的標準定義

關於har格式的詳細文件: http://groups.google.com/group/http-archive-specification/

那如何在Fiddler裡面將Session匯出har呢

image
image
image

那用程式碼如何匯出呢?


//這種方式為匯出到變數注意是Fiddler4.6.2.0版本之後支援的
varoExportOptions=FiddlerObject.createDictionary();
oExportOptions.Add(“ExportToString”,“true”);
FiddlerApplication.DoExport("HTTPArchivev1.2",oSessions,oExportOptions,null);
//這個就是了
varsOutput:String=oExportOptions[“OutputAsString”];


//這種方式為匯出到指定路徑
varoExportOptions=FiddlerObject.createDictionary();
oExportOptions.Add("Filename","對應的路徑");
FiddlerApplication.DoExport("HTTPArchivev1.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

隨便找到一個空白的地方,然後把下面的程式碼複製進去:


publicstaticRulesOption("關閉請求體轉程式碼","生成程式碼")
varm_DisableReuqest:boolean=false;

publicstaticRulesOption("關閉返回體轉程式碼","生成程式碼")
varm_DisableResponse:boolean=false;

publicstaticContextAction("C#-httpclient","生成程式碼")
functiondo1(arrSess:Session[]){doStar(arrSess,"csharp","httpclient");}
publicstaticContextAction("C#-restsharp","生成程式碼")
functiondo2(arrSess:Session[]){doStar(arrSess,"csharp","restsharp");}

publicstaticContextAction("Java-okhttp","生成程式碼")
functiondo3(arrSess:Session[]){doStar(arrSess,"java","okhttp");}
publicstaticContextAction("Java-asynchttp","生成程式碼")
functiondo4(arrSess:Session[]){doStar(arrSess,"java","asynchttp");}
publicstaticContextAction("Java-nethttp","生成程式碼")
functiondo5(arrSess:Session[]){doStar(arrSess,"java","nethttp");}
publicstaticContextAction("Java-unirest","生成程式碼")
functiondo6(arrSess:Session[]){doStar(arrSess,"java","unirest");}

publicstaticContextAction("Kotlin-okhttp","生成程式碼")
functiondo7(arrSess:Session[]){doStar(arrSess,"kotlin","okhttp");}

publicstaticContextAction("JavaScript-xhr","生成程式碼")
functiondo8(arrSess:Session[]){doStar(arrSess,"javascript","xhr");}
publicstaticContextAction("JavaScript-jquery","生成程式碼")
functiondo9(arrSess:Session[]){doStar(arrSess,"javascript","jquery");}
publicstaticContextAction("JavaScript-fetch","生成程式碼")
functiondo10(arrSess:Session[]){doStar(arrSess,"javascript","fetch");}
publicstaticContextAction("JavaScript-axios","生成程式碼")
functiondo11(arrSess:Session[]){doStar(arrSess,"javascript","axios");}

publicstaticContextAction("Node-native","生成程式碼")
functiondo12(arrSess:Session[]){doStar(arrSess,"node","native");}
publicstaticContextAction("Node-request","生成程式碼")
functiondo13(arrSess:Session[]){doStar(arrSess,"node","request");}
publicstaticContextAction("Node-fetch","生成程式碼")
functiondo14(arrSess:Session[]){doStar(arrSess,"node","fetch");}
publicstaticContextAction("Node-axios","生成程式碼")
functiondo15(arrSess:Session[]){doStar(arrSess,"node","axios");}
publicstaticContextAction("Node-unirest","生成程式碼")
functiondo16(arrSess:Session[]){doStar(arrSess,"node","unirest");}

publicstaticContextAction("Python3-http.client","生成程式碼")
functiondo17(arrSess:Session[]){doStar(arrSess,"python","python3");}
publicstaticContextAction("Python-requests","生成程式碼")
functiondo18(arrSess:Session[]){doStar(arrSess,"python","requests");}

publicstaticContextAction("ObjectiveC-nsurlsession","生成程式碼")
functiondo19(arrSess:Session[]){doStar(arrSess,"objc","nsurlsession");}

publicstaticContextAction("Ruby-net::http","生成程式碼")
functiondo20(arrSess:Session[]){doStar(arrSess,"ruby","native");}

publicstaticContextAction("Swift-nsurlsession","生成程式碼")
functiondo21(arrSess:Session[]){doStar(arrSess,"swift","nsurlsession");}

publicstaticContextAction("powershell-webrequest","生成程式碼")
functiondo22(arrSess:Session[]){doStar(arrSess,"powershell","webrequest");}
publicstaticContextAction("powershell-restmethod","生成程式碼")
functiondo23(arrSess:Session[]){doStar(arrSess,"powershell","restmethod");}

publicstaticContextAction("Shell-curl","生成程式碼")
functiondo24(arrSess:Session[]){doStar(arrSess,"shell","curl");}
publicstaticContextAction("Shell-httpie","生成程式碼")
functiondo25(arrSess:Session[]){doStar(arrSess,"shell","httpie");}
publicstaticContextAction("Shell-wget","生成程式碼")
functiondo26(arrSess:Session[]){doStar(arrSess,"shell","wget");}

publicstaticContextAction("Go-NewRequest","生成程式碼")
functiondo27(arrSess:Session[]){doStar(arrSess,"go","native");}

publicstaticContextAction("Clojure-clj_http","生成程式碼")
functiondo28(arrSess:Session[]){doStar(arrSess,"clojure","clj_http");}

publicstaticContextAction("C-Libcurl","生成程式碼")
functiondo29(arrSess:Session[]){doStar(arrSess,"c","libcurl");}

publicstaticContextAction("PHP-curl","生成程式碼")
functiondo30(arrSess:Session[]){doStar(arrSess,"php","curl");}
publicstaticContextAction("PHP-http1","生成程式碼")
functiondo31(arrSess:Session[]){doStar(arrSess,"php","http1");}
publicstaticContextAction("PHP-http2","生成程式碼")
functiondo32(arrSess:Session[]){doStar(arrSess,"php","http2");}

publicstaticfunctiondoStar(oSessions:Session[],target:String,client:String){
//注意看這裡,請下載我給的這2個exe並替換成你電腦中正確的目錄
varhttpsnippet="E:\\workspace\\github\\test\\httpsnippet.exe";
varquicktype="E:\\workspace\\github\\test\\quicktype.exe";
varoExportOptions=FiddlerObject.createDictionary();
vartempPath2=System.IO.Path.Combine(System.IO.Path.GetTempPath(),"fiddler.har");
if(System.IO.File.Exists(tempPath2)){
System.IO.File.Delete(tempPath2);
}
vartempPath=System.IO.Path.Combine(System.IO.Path.GetTempPath(),"fiddler.json");
if(System.IO.File.Exists(tempPath)){
System.IO.File.Delete(tempPath);
}
vartempRequestBodyPath=System.IO.Path.Combine(System.IO.Path.GetTempPath(),"fiddler_requestBody.json");
if(System.IO.File.Exists(tempRequestBodyPath)){
System.IO.File.Delete(tempRequestBodyPath);
}
vartempResponseBodyPath=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("HTTPArchivev1.2",oSessions,oExportOptions,null);
System.IO.File.Move(tempPath2,tempPath);
if(!System.IO.File.Exists(tempPath)){
MessageBox.Show("生成程式碼失敗","Noaction");
return;
}
varrtPath=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("生成程式碼錯誤","Noaction");
return;
}
varfile=System.IO.Directory.GetFiles(rtPath);
if(file.Length!=1){
MessageBox.Show("生成程式碼錯誤","Noaction");
return;
}
varjson=System.IO.File.ReadAllText(file[0]);
System.IO.File.Delete(file[0]);
varrtPath1=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("程式碼生成成功,已複製到剪貼簿");
}

staticfunctiongetJsonCode(file:String,tempRequestBodyPath:String,rtPath:String,rtPath1:String,target:String,type:String):String{
varjson="";
vartmp1="";
if(target=='csharp'){
tmp1="--quiet--telemetrydisable--featuresjust-types--array-typelist--no-check-required--namespace\"Fiddlers\"--lang\""+target+"\"--top-level\""+type+"Model\"\""+tempRequestBodyPath+"\""+"-o"+"\""+rtPath1+"\"";
}
elseif(target=='kotlin'){
tmp1="--quiet--telemetrydisable--frameworkjust-types--lang\""+target+"\"--top-level\""+type+"Model\"\""+tempRequestBodyPath+"\""+"-o"+"\""+rtPath1+"\"";
}
elseif(target=='java'){
tmp1="--quiet--telemetrydisable--array-typelist--just-types--package\"Fiddlers\"--lang\""+target+"\"--top-level\""+type+"Model\"\""+tempRequestBodyPath+"\""+"-o"+"\""+rtPath+"\\test"+"\"";

}
else{
tmp1="--telemetrydisable--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("packagequicktype","");
}

if(target=='java'){
varjavaFiles=System.IO.Directory.GetFiles(rtPath,"*.java");
if(javaFiles.Length>0){
json+="\r\n//"+type+"-POJO\r\n";
for(vari:int=0;i<javaFiles.Length;i++)
{
json+=System.IO.File.ReadAllText(javaFiles[i]).Replace("packageFiddlers;","")
System.IO.File.Delete(javaFiles[i]);
}
}
}
returnjson;
}

staticfunctiondoProcess(file:String,paramsList:String):Boolean{
varprocess=newSystem.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();
returntrue;
}

然後下載:httpsnippet和quicktype這2個可執行檔案。獲取下載地址的方法:關注文末公眾號後傳送文字 :Fiddler ,會告訴你百度網盤連結!

下載zip包後然後把這2個檔案解壓到你的電腦的某個目錄。

在回到指令碼中找到 doStar 方法中修改成正確的目錄。

Enjoy!!!

關注公眾號一起學習


如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕,您的“推薦”將是我最大的寫作動力!歡迎各位轉載,轉載文章之後須在文章頁面明顯位置給出作者和原文連線,謝謝。