Fiddler抓包一键生成调用代码

首先我们的需求场景是

用Fiddler抓到某个接口调用后,用代码来模拟调用,一般我们写代码会有3个步骤:

  • 1设置http请求相关的参数:header,method,url,cookie等

  • 2设置post的body(如果是post的话需要)

  • 3拿到返回的body(一般我们需要拿到接口的返回体进行解析)

假如这3个步骤的代码全部都能一键生成那该多爽,我终于站在巨人的肩膀上搞定了!

搞定的效果如下图:

f9cd7c0025259fb9f9deb2d2d198d5d8.gif
image

上面是对于csharp 采用自带的 HttpClient的代码生成演示,还可以针对java kotlin,python,nodejs等

本篇的主要功能都是在FiddlerScript里面完成,主要包含3块扩展

  • 增加自定义右键菜单

  • 增加控制开关

  • 代码获取请求上下文并导出har

  • 使用脚本完成process的封装并调用

1. 增加右键菜单

点中某个Session然后点击右键菜单,选择生成指定语言的代码,这样使用起来最方便,如下图:ddd5b4bccd855cf582cb3512880deb10.png

新增右键菜单的扩展方式是 【一个ContextAction+一个function】

例如:

public static ContextAction("C#-httpclient", "生成代码")function do1(arrSess: Session[]) {  doStar(arrSess, "csharp","httpclient"); }

代表新增一个 一级菜单叫 生成代码,二级菜单叫 "C#-httpclient"

下面的function就是点击需要响应的方法实现,默认是Session数组,因为可以选择多个。

2. 控制开关

前面说有3个步骤,除了第一个步骤是核心的,其他2个步骤都是将json转为实体类定义,是辅助的。所以都设置开关可以人为控制要不要生成这2块的代码

如下图:

00bec3017ae94102f7a9ce8634dbb1a5.png
image

新增开关的方式是定义【一个RulesOption+一个对应接收的变量】

public static RulesOption("关闭请求体转代码", "生成代码")var m_DisableReuqest: boolean = false;

代表新增一个 以及菜单叫生成代码,二级菜单叫 "关闭请求体转代码",类型是bool,因为下面对应接收的变量是布尔类型!

3. 通过选中Session拿到整个请求的上下文

上下文包括,请求的各种参数,比如url,header,method,request,response等

a5d25ba1f6e2175e9dd72d1d4863aac7.png
image

Fillder有一个api可以导出har文件,这个har格式是谷歌提出来的一个用来描述一个请求的标准定义,如上图

关于har格式的详细文档:http://groups.google.com/group/http-archive-specification/

那如何在Fiddler里面将Session导出har呢

b244ed27b1604b3bfd27babc03bc2217.png
image
4e1343ee070e2fb2db4e439d029c992d.png
image
5062bcaf9d3afc04a91ead838b3a6986.png
image

那用代码如何导出呢?

//这种方式为导出到变量 注意是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的脚本编辑器中即可:

首先打开脚本编辑器:

0250739bc98655f64db755c8090d1f12.png
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的语法),什么语言不重要,重要的是实现了我想要的效果。


我是正东,学的越多不知道也越多。如果决定去深究一个东西, 一定要完全搞懂, 并认真总结一篇博客让以后能在短时间拾起来 ( 因为不搞懂你很难写一篇半年后还能理解的博客 )

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/296752.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DexClassLoader的使用

版权声明&#xff1a;您好&#xff0c;转载请留下本人博客的地址&#xff0c;谢谢 https://blog.csdn.net/hongbochen1223/article/details/47146613 在Java环境中,有个概念叫做”类装载器(Class Loader)”,其作用是动态加载Class文件.标准的Java SDK中有一个ClassLoader类,借助…

这才是老公的正确用法,不吃就往死里打......

1 倒是好办法就是有点儿费爸爸▼2 一只被主人遗弃的小熊的奇幻旅程▼3 小子&#xff0c;你单身的命运gu7在你把美女老师撂倒那一刻就注定了...▼4 张萌姐姐自我肯定式唱歌▼5 &#xff1f;&#xff1f;&#xff1f;有被冒犯到▼6 听说昨天有个少年28岁就退休了▼7 哪个男…

C# WPF MVVM模式下在主窗体显示子窗体并获取结果

01—前言在winform中打开一个新的子窗体很简单&#xff0c;直接实例化窗体并show一下就可以&#xff1a;Form2 f2 new Form2();f2.Show();或者Form2 f2 new Form2();f2.ShowDialog();但是&#xff0c;在wpf的mvvm模式下&#xff0c;这种方法是行不通的&#xff0c;因为逻辑是…

Exchange 2010发现拓扑失败

今天跟大家继续分享一个我在项目中遇到的问题哈&#xff0c;希望对大家今后的项目排错有帮助。问题背景&#xff1a;企业主域控从 Window Server 2003升级为Windows Server 2012 R2具体实施方法可以参考我之前的文章(http://horse87.blog.51cto.com/2633686/1613268)在顺利升级…

html引用单文件组件,vue之单文件组件 纯网页方式引入

上一节的vue组件开发是把组件内容统一放到了一个js文件里面里面写上模板字符串(引用组件) 这种方式还需要拼接转义 写法非常丑陋vue贴心的帮我们封装了单文件组件 可以不用再模板里面拼接字符串下面看下写法由于我们目前没有使用webpack和vue-cli等构建工具(为了快速学习vue的语…

足不出户,游遍七大洲,不可错过的14部地理纪录片!

见识是超越时间与空间的力量&#xff0c;使人身未行&#xff0c;而心已至之。今天的资源分享就从七大洲为切入点&#xff0c;为各位献上最值得观看的14部地理纪录片&#xff0c;与各位一起探索各大洲的独一无二的自然与人文景观&#xff0c;从这些丰富的影像中&#xff0c;不仅…

在Cocos2d中实现能够惯性拖动的选择界面

苹果的应用讲究用户体验 有的时候仔细想想 的确&#xff0c;很多细节决定了用户体验 比如说惯性拖动 可以说之前没有任何一家厂商能把触摸惯性拖动做的像苹果的UI那么流畅 Cocos2D中实现能够惯性拖动的选择界面 完成的效果&#xff1a; 制作一个简单的图层&#xff0c;通过传入…

SignalR在React/Go技术栈的实践

哼哧哼哧半年&#xff0c;优化改进了一个运维开发web平台。本文记录SignalR在react/golang 技术栈的生产小实践。01背景有个前后端分离的运维开发web平台&#xff0c; 后端会间隔5分钟同步一次数据&#xff0c;现在需要将最新一次同步的时间推送到web前端。说到[web服务端推送]…

16张扎心漫画,戳中女生私密日常,每一幕都很真实

全世界只有3.14 % 的人关注了爆炸吧知识比利时的插画师Planet Prudence&#xff0c;画了很多女生的真实日常&#xff0c;每一幕都很戳心&#xff0c;一起来看看吧。别人的痘痘一长就是一个&#xff0c;我一长就是一片。买买买的时候爽得要命&#xff0c;要穿的时候总觉得自己没…

Magicodes.IE 2.5.6.2发布

2.5.6.22021.10.13支持自定义列字体颜色&#xff0c;具体见PR#342&#xff0c;感谢xiangxiren修复日期格式化的问题&#xff0c;具体见PR#344&#xff0c;感谢ccccccmd2.5.6.12021.10.06修复 #337&#xff0c;bool?类型导出的映射问题2.5.6.02021.10.05合并Magicodes.EPPlus到…

一个让我很不爽的外包项目——奔驰Smart2015新官网

七月份的下半个月&#xff0c;有幸做了奔驰 Smart 2015年新官网&#xff0c;包括手机端和PC端的宣传页&#xff0c;地址&#xff1a; PC端手机端这里&#xff0c;为了证明这个是一个事实&#xff0c;我还特意的留存了两张截图&#xff1a; 这里只想说明这么几个问题&#xff1a…

为什么饮料瓶大都是圆的,牛奶盒却是方的?原因你想不到

全世界只有3.14 % 的人关注了爆炸吧知识每日看着电视玩着手机再喝着饮料那是相当美好但是喝了这么久的饮料你有没有想过一个问题为什么饮料瓶一般都是圆的&#xff1f;而牛奶盒却是方的&#xff1f;图片来源网络有的人可能会说饮料瓶要拿在手上当然是圆的舒服啊拿着一个方形的饮…

IIS相关问题及解决方案

1、问题&#xff1a;HTTP 错误 500.19 - Internal Server Error无法访问请求的页面,因为该页的相关配 可能原因&#xff1a;在自己使用IIS发布网站之后&#xff0c;自己所使用的当前账户的密码改变了。 解决方法&#xff1a;将用户才密码改回来即可.... 2. 转载于:https://www.…

博客园html源码编辑出错,博客园小技巧

作者&#xff1a;Vamei 出处&#xff1a;http://www.cnblogs.com/vamei 欢迎转载&#xff0c;也请保留这段声明。谢谢&#xff01;在博客园写博的半年中&#xff0c;我有时会纠结于一些诸如写作格式和显示效果之类的小问题。我想任何一个热衷于在这里写博客的人都可能会遇到类似…

使用零代码平台构建应用,应该怎样转变思路?

最近两年&#xff0c;越来越多的各类零代码产品在市场上出现&#xff0c;与此同时&#xff0c;企业的数字化转型的速度也越来越快&#xff0c;零代码产品已然成为了帮助企业数字化转型的利器。技术也在不断地演进&#xff0c;其核心目的就是让开发人员能够更专注于业务逻辑&…

看了这几幅图,感觉自己物理白学了!

全世界只有3.14 % 的人关注了爆炸吧知识看完觉得自己即将成为21世纪最伟大的科学家&#xff01;据说&#xff0c;物理老师看到这几幅图&#xff0c;会说不出话来……不信&#xff0c;转给你们老师看看&#xff0c;嘿嘿嘿……来源&#xff1a;物理知识大全

在Web应用中使用localforage存储离线数据

在现代Web应用中&#xff0c;我们经常会需要在本地存储一些数据&#xff0c;一方面记住用户的一些状态&#xff0c;或个性化设置&#xff0c;尤其是可以缓存一些常用&#xff08;甚至全部&#xff09;的数据&#xff0c;实现更加强大和丰富的本地交互体验。传统上说&#xff0c…

出差一定要给孩子带特产

1 这就是热恋期管不住自己的情侣▼2 热恋期过了...▼3 这该夸你腰细呢&#xff1f;还是脸大呢&#xff1f;▼4 听起来...不是挺好的吗▼5 由于新冠病毒&#xff0c;美国GCW选手都保持着一定距离改用原力来进行比赛▼6 她们太菜了你跟她们好以后肯定疯狂掉分▼7 出差一定…

计算机用户名密码策略,设置域用户帐户密码策略

从安全和易用考虑&#xff0c;普通域用户的帐户策略必须满足一下要求&#xff1a;u 密码长度至少3位u 最长使用期限60天u 密码必须符合复杂性要求u 密码最短使用0天u 帐户锁定阀值7次u 帐户锁定时间30分钟u 复位帐户锁定计数器30分钟任务:u 使用默认域策略设置域用户帐户策略u …

优秀的硕博士们,他们的朋友圈都有什么特点?

全世界只有3.14 % 的人关注了爆炸吧知识很多同学都会有这种感觉&#xff0c;读了硕士博士后&#xff0c;兴趣会突然间发生很大变化&#xff0c;发朋友圈也会不一样了。例如&#xff0c;合格的学术研究者&#xff0c;要快速、全面的获取各种最新文献和学界动态&#xff1b;还要持…