Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试

Stella981
• 阅读 694

之前在《关于 WEB/HTTP 调试利器 Fiddler 的一些技巧分享》中系统的介绍过 Fiddler 的原理与一些常见技巧,但那篇文章只是入门科普,并不深入,今天要介绍到的内容相对更加高级与深入,扩展性更好,功能更加强大。

1、Fiddler Script

1.1 Fiddler Script简介

在web前端开发的过程中,fiddler是最常使用的一款调试工具。在大多数情况下,通过fiddler默认菜单的功能就可以基本满足开发者的调试需求,然而如果需要满足更复杂的调试场景时,单纯通过fiddler菜单已无法达到开发者的调试要求。

如果用户需要修改http请求的头部或者修改http请求的应答头部,只能通过设置断点的方式,设置断点有两种方法:

第一种:打开Fiddler 点击Rules-> Automatic Breakpoint ->Before Requests(这种方法会中断所有的会话),消除断点的方法,点击Rules-> Automatic Breakpoint ->Disabled。

第二种: 在命令行中输入命令: bpu http://www.qq.com,这种方法只会中断http://www.qq.com,消除断点的方法就是在命令行中输入命令 bpu。

但是这两种方法当程序运行到断点处的时候都会停止,需要手动点击“Run to Completion”重新启动,非常不方便。而且通过fiddler的菜单功能,无法修改http请求的URI。此时Fiddler Script的优点就体现出来了,Fiddler Script的本质其实是用JScript.NET语言写的一个脚本文件CustomRules.js,语法类似于C#, 通过修改CustomRules.js可以很容易的修改http的请求和应答,不用中断程序,还可以针对不同的URI做特殊的处理,除此之外还可以根据开发者的需要去定制菜单。

脚本文件CustomRules.js位于C:\Documents and Settings\[your user]\My Documents\Fiddler2\Scripts\CustomRules.js 下,你也可以在Fiddler 中打开CustomRules.js 文件, 启动Fiddler, 点击菜单Rules->Customize Rules。Fiddler Script 的官方帮助文档的地址是:http://www.fiddler2.com/Fiddler/dev/ScriptSamples.asp。

可以直接编辑CustomRules.js文件,也可以下载 Fiddler Script Editor来编辑,下载的地址是http://www.fiddler2.com/fiddler/fse.asp。Fiddler Script Editor 提供了语法高亮,以及智能提示的功能, 方便编辑。

1.2 Fiddler Script用法

1.2.1 修改session样式

  • 修改session的显示样式(颜色等)

     // 修改session中的显示样式  oSession["ui-color"] = "orange";

Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试

  • 修改http请求和应答

在如下函数中修改http请求头:

static function OnBeforeRequest(oSession: Session)

在如下函数中修改http应答:

static function OnBeforeResponse(oSession: Session)

在如下函数中fiddler命令(右下角的命令行):

static function OnExecAction(sParams: String[])

例如http请求中,对域名为p.21kunpeng.com的URI的http请求内容作修改:

if (oSession.host.indexOf("p.21kunpeng.com") > -1) {
 // 修改session中的显示样式
 oSession["ui-color"] = "orange";
 // 移除http头部中的MQB-X5-Referer字段
 oSession.oRequest.headers.Remove("MQB-X5-Referer");
 // 修改http头部中的Cache-Control字段
 oSession.oRequest["Cache-Control"] = "no-cache";
 // 修改host
 oSession.host = "kyfw.12306.cn"; 
 // 修改Origin字段
 oSession.oRequest["Origin"] = "https://kyfw.12306.cn";
 // 删除所有的cookie
 oSession.oRequest.headers.Remove("Cookie");
 // 新建cookie
 oSession.oRequest.headers.Add("Cookie", "username=yulesyu;");
 // 修改Referer字段
 oSession.oRequest["Referer"] = "https://kyfw.12306.cn/otsweb/loginAction.do";

 // 获取Request中的body字符串
 var strBody=oSession.GetRequestBodyAsString();
 // 用正则表达式或者replace方法去修改string
 strBody=strBody.replace("1111","2222");
 // 弹个对话框检查下修改后的body               
 FiddlerObject.alert(strBody);
 // 将修改后的body,重新写回Request中
 oSession.utilSetRequestBody(strBody);
}

例如http应答中,如果含有location并且location中含有字段initQueryUserInfo,则修改为http://p.21kunpeng.com

var location = oSession.oResponse.headers["Location"];
 if(oSession.PathAndQuery.indexOf("initQueryUserInfo") != -1) 
 {      
    oSession.oResponse.headers["Location"] = "http://p.21kunpeng.com";
 }

1.2.2 修改URI

将请求URI中http协议替换成https协议,例如:

oSession.fullUrl = "https" + oSession.fullUrl.Substring(oSession.fullUrl.IndexOf(':'));

1.2.3 定制菜单

  • 定制rule菜单的子菜单

例如在rule菜单下定义一个修改http头部中的Q-UA字段的子菜单:

/ 定义名为Q-UA的子菜单
RulesString("&Q-UA", true);
// 生成Q-UA子菜单的radio选项
RulesStringValue(0,"x5_4.3", "ADRQBX43_GA/420411&X5MTT_3/024200&ADR&346014& U9200 &0&9065&Android4.0.3 &V3")
RulesStringValue(1,"x5_5.0", "ADRQBX50_B1/500620&X5MTT_3/025001&ADR&346014& U9200 &21013&9255&Android4.2.2 &V3")
RulesStringValue(2,"ios4.1", "IQB41_GA/370015&IMTT_3/370015&IPH&406040&iPodTouch4G&50003&8917&V3")
RulesStringValue(3,"ios5.0", "IQB50_GA/500028&IMTT_3/500028&IPH&406040&iPhone4&50001&9219&iOS7.0.4&V3")
RulesStringValue(4,"&Custom...", "%CUSTOM%")
public static var sQUA: String = null;
还需要在OnBeforeRequest函数中加入:

 // Q-UA Overrides
 if (null != sQUA) {
     oSession.oRequest["Q-UA"] = sQUA; 
 }
  • 定制tool菜单的子菜单

    // tool menu  public static ToolsAction("tool menu")  function DoManualYules(){      FiddlerObject.alert("tool menu"); // 根据需要定制  }

  • 定制右键子菜单

     // tool menu  public static ContextAction("context menu")  function DoOpenInIE(oSessions: Fiddler.Session[]){      FiddlerObject.alert("context menu"); // 根据需要定制  }

1.3 Fiddler Script限速

限速对于web前端研发是非常重要的,由于开发者的机器一般配置都很高,并且都是把相关文件代理到本地来调试程序,所以很难模拟到用户的真实使用情况,如正在下载js,css等静态资源的时候,页面的一个渲染情况。当网速很慢的时候,我们更希望看到的是先渲染出用户界面,而不是让用户看到一片空白。那么这个时候,网络限速就能很方便在localhost针对类似的情况来做性能调试与优化。

我们可以通过fiddler来模拟限速,因为fiddler本来就是个代理,它提供了客户端请求前和服务器响应前的回调接口,我们可以在这些接口里面自定义一些逻辑。Fiddler的模拟限速正是在客户端请求前来自定义限速的逻辑,此逻辑是通过延迟发送数据或接收的数据的时间来限制网络的下载速度和上传速度,从而达到限速的效果。

fiddler提供了一个功能,让我们模拟低速网路环境。启用方法如下:Rules → Performances → Simulate Modem Speeds。勾选之后,你会发现你的网路瞬间慢下来了很多。至于慢下来后网络速度是多少,则由CustomRules.js 中如下程序控制的:

Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试

 ...
 var m_SimulateModem: boolean = true;
 ...
 if (m_SimulateModem) {
    // Delay sends by 500ms per KB uploaded.
     oSession["request-trickle-delay"] = "500"; 
     // Delay receives by 150ms per KB downloaded.
     oSession["response-trickle-delay"] = "150"; 
 }
 ...

算法就是 1000/下载速度 = 需要delay的时间(毫秒),比如50kB/s 需要delay20毫秒来接收数据,所以根据你需要的网络速度来修改上述值。

【注】:存档之后,原本已经勾选的Simulate Modem Speeds 会被取消勾选,需要再到Rules → Performances → Simulate Modem Speeds 勾选,同时需要注意一定要禁用浏览器代理插件,以及修改完成后重启浏览器才能生效。

2、Fiddler AutoResponder:请求、响应应答与替换

AutoResponder 是 Fiddler 比较重要且比较强大的功能之一。可用于拦截某一请求,并重定向到本地的资源,或者使用Fiddler的内置响应。可用于调试服务器端代码而无需修改服务器端的代码和配置,因为拦截和重定向后,实际上访问的是本地的文件或者得到的是Fiddler的内置响应。

2.1 线上档案替换为本机端档案

方法是点下Fiddler 右上的AutoResponder ,勾选Enable automatic responses 和Unmatched requests passthrough ,按下右边的Add ;再将下方的Rule Editor 第一行修改为线上档案位址(线上档案位址也可以使用Regular Expression ,开头加上regex: 即可。);按下Rule Editor 第二行右边的箭头,选择Find a file ... ;选择要替换成的本机端档案,按下右边的SAVE ,大功告成!

Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试

将线上档案替换成另一个线上档案,步骤几乎一模一样,差别仅在Rule Editor 第二行填入的是另一线上档案位址:

Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试

更多AutoResponder的说明请参考Fiddler官方文件- AutoResponder Reference 。

2.2 Fiddler替换HTTP Request Host

这边指的替换HTTP Request Host是,所有原先发到a.com的HTTP Request , Fiddler都帮你转发到b.com ,而在浏览器中毫无感觉。 测试debug过程中常有这种需求,例如用www. dev.demo.com替换 www.demo.com

替换的方法有两种,一种是暂时的,一种是永久的。 暂时的方法是在Fiddler 左下角输入:

urlreplace www.demo.com www.dev.demo.com

Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试

按下Enter ,所有原先发到www.demo.com 的HTTP Request 就转发到www.dev.demo.com 了。

要清除转发,请在同一位置输入:

urlreplace

按Enter 就可以了。

更详细的说明请参考Fiddler官方说明文件- QuickExec Reference 。 可以发现urlreplace 做的是整个网址字串的取代,所以可以动手脚的地方不只于此。

永久的方法是修改Fiddler的CustomRules.js ,注意是.js ! 点下Fiddler 上方的Rules ,再点Customize Rules :

如果有安装FiddlerScript Editor ,会用FiddlerScript Editor开启CustomRules.js ,否则会用笔记本开启。 或者也可以到「我的文件 Fiddler2 Scripts 」直接编辑CustomRules.js 。

请先在CustomRules.js 找到:

  static function OnBeforeRequest ( oSession : Session ) {
   // ...
 }
在函式OnBeforeRequest 中加入:

  if ( oSession . HostnameIs ( 'www.demo.com' ) )
   oSession . hostname = 'www.dev.demo.com' ;

将CustomRules.js 存档, Fiddler 会自动重新载入CustomRules.js ,原先发到www.demo.com 的HTTP Request 就会自动转发到www.dev.demo.com

更详细的说明请参考Fiddler官方说明文件- Script Samples 。

3、实战 HTTP 请求、响应的断点调试

断点命令介绍:

  • bpu在请求开始时中断,

  • bpafter在响应到达时中断,

  • bps在特定http状态码时中断,

  • bpv/bpm在特定请求method时中断。

提示:命令输入区域输入help,回车执行会打开一页面详细介绍fiddler的所有命令。

也可以在菜单栏设置断点,是针对所有的会话请求,不大实用,建议用命令。

以bpu为例演示断点功能:

(1)以淘宝无线H5为例,在浏览器打开m.taobao.com首页。

(2)在Fiddler命令行输入区输入“bpu”回车执行清掉原有的断点,然后输入“bpu m.taobao.com/search.htm”回车执行,接下来就会中断URL中包含此地址的请求。

Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试

(3)在浏览器淘宝首页顶端搜索框输入“充气娃娃”后点击搜索,此时请求被中断,在Fiddler会话列表面板看到以红色小图标开头被中断的会话

Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试

(4)点击会话列表中被中断的会话,依次进入Inspectors-->WebForms。此时请求并未发出,q参数即为查询关键字,我们修改为“nike”,然后点击“Break on Response”按钮。注:在这里实现修改了请求数据,其它的post数据,甚至是headers里的cookie、referer、user-agent等都可以修改。

Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试

(5)右边面板Response区有响应内容了,这时Fiddler再次中断了response,响应已到达Fiddler代理,但还没返回给浏览器。点击Inspectorsg下Response区的“response is encoded and may need to decoded before inspection.Click here to transform”后,即可在TextView tab看到返回的html内容。在这里修改response中的title部分,然后点击“Run to Completino"把修改后的response返回给浏览器。

Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试

(6)回到浏览器,搜索出关键字为“nike”的结果,而不是“充气娃娃”,标题也被修改为“搜索充气娃娃”。

Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试

其他:

  • 命令行输入 go 会断续执行所有中断,再次输入 bpu 会清除所有的断点。

  • 如上第四点图所示,这里有很多的操作选择,就是选择输出内容,选择之后,实际的响应数据就会这些替代,特别是最后一个find 操作a file:这个我们可以中断一个图片,然后这里选择本地的一张图片,这样我们就可以替换页面的图片。比较强大的场景就是例如现网js出了问题,但是一般现网的js是压缩过的,在firebug中根本无法调试,这样我们可以把它映射到本地的一个原始版本,这样firebug就会拿到一份原始的js,就可以方便的调试了。

4、Fiddler 远程捕获 Android/iPhone 请求

Android 或者 iPhone 上 APP 的请求对用户来说是不可见的,不像 PC 上用浏览器 F12 可以很方便的调试,我们有没有办法去调试呢?

答案必然是有的,那就是 Fiddler 的代理可以支持 APP 远程连接与抓包调试。过程如下:

(1)Start Fiddler then open the Fiddler Options window

(2)and in the Connections tab, ensure Allow remote computers to connect is checked.

(3)In the Connections tab, check Act as system proxy on startup and verify what port is set (eg. 8888).

        Once you've saved those settings you need to stop and re-start Fiddler.

Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试

(4)Once Fiddler has re-started, verify that the Capture Traffic menuitem is ticked.

(5)You need to know your computer's wireless-network IP address to configure the iPhone. This screenshots shows the Command Prompt > ipconfig output:

(6)With the computer IP address and Fiddler port, go to your iPhone/Android's Wifi Settings and scroll down to the HTTP Proxy, choose Manual and input the Fiddler proxy info:

Note:if you change  iPhone/Android's Wifi Proxy Settings,you must re-connect your wifi to effect.

Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试

(7)If everything has been setup right, anything you do in Safari or other internet applications (like, say Microsoft Tag Reader) will be logged in the Fiddler window. 

Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试

It's extremely useful for testing/debugging - have fun!

5、使用Fiddler把请求从HTTPS改成HTTP

为什么我要把请求从 HTTPS 改成 HTTP?这是因为生产环境是 HTTPS 的,而测试环境却是 HTTP 的,我要在测试环境测试应用,所以需要把请求从 HTTPS 改成 HTTP。为什么我不在测试环境部署一套 HTTPS 证书?这是因为 HTTPS 证书属于敏感信息。
最开始,我的想法是应用打包的时候打两个包,分别是正式包和测试包,正式包使用 HTTPS 来请求服务器,测试包使用 HTTP 来请求服务器。这个方法当然可以工作,不过实在是太蠢了!好在公司的测试兄弟告诉我可以用 Fiddler 来搞定这个问题:

也就是说,Fiddler 在这里就是一个「中间人」的角色,当客户端发送 HTTPS 请求 给服务器的时候,Fiddler 拦截到请求,将其解密后以 HTTP 的形式转发给服务器,然后再把服务器的响应加密成 HTTPS 返回给客户端。

了解了原理之后,我们只要一小段 FiddlerScript 代码就能完成此功能:

if (oSession.isHTTPS && oSession.hostname == "test.com") {
    oSession.fullUrl = "http://test.com" + oSession.PathAndQuery;
}

添加的位置:在 FiddlerScript 标签里搜索 OnBeforeRequest 方法,加到最上面即可:

Fiddler 高级用法:Fiddler Script 与 HTTP 断点调试

6、Refer:

[1] Fiddler的高级用法-Fiddler Script

http://cube.qq.com/?p=973

[2] 用Fiddler模拟低速网络环境

http://caibaojian.com/fiddler.html

[3] Fiddler (二) Script 用法

http://www.cnblogs.com/tankxiao/archive/2012/04/25/2349049.html

[4] 抓包工具:Fiddler 2-强大功能之一 断点

http://chessman-126-com.iteye.com/blog/2001288

[5] 【HTTP】Fiddler(三)- Fiddler命令行和HTTP断点调试

http://blog.csdn.net/ohmygirl/article/details/17855031

[6] 【HTTP】Fiddler(二) - 使用Fiddler做抓包分析

http://blog.csdn.net/ohmygirl/article/details/17849983

[7] 【HTTP】Fiddler(一) - Fiddler简介

http://blog.csdn.net/ohmygirl/article/details/17846199

[8] Using QuickExec

http://docs.telerik.com/fiddler/knowledgebase/quickexec

[9] Add Rules to Fiddler

http://docs.telerik.com/fiddler/extend-fiddler/addrules

[10] 关于 WEB/HTTP 调试利器 Fiddler 的一些技巧分享

http://my.oschina.net/leejun2005/blog/151103

[11] Monitoring iPhone web traffic (with Fiddler)

http://conceptdev.blogspot.com/2009/01/monitoring-iphone-web-traffic-with.html

[12] How to change proxy settings in Android (especially in Chrome)

http://stackoverflow.com/questions/21068905/how-to-change-proxy-settings-in-android-especially-in-chrome

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
2年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这