Fiddler模拟测试之简单Fiddler脚本拼接动态的响应体(ResponseBody)
前言
测试前端页面时,在服务端构造数据如果困难,此时可以使用Fiddler
模拟服务端响应的数据,一般情况下Fiddler
的AutoResponder
和Quickexec
功能就可以大部分问题。
但是类似JQuery
请求的一些接口,AutoResponder
和quickexec
功能将难以满足我们的需求。
这些接口的请求URL地址
会带一个时间戳或者随机数字,服务端返回的报文中的会将这个随机数回传,客户端会检查是否匹配。
例子
搞一个某电商网站的页面http://tss.suning.com/ticket/tss/wap/201912110012064863.html
这个页面的价格等信息是由如下接口从服务器获取的。
http://ds.suning.com/ds/generalForTile/000000000133855708__2_0070062355-025-2--1-6035372306-ds0000000004264.jsonp?callback=ds0000000004264&_=1590408938027
客户端生成一个随机字符串ds0000000004264
并用callback
参数告诉服务端。使用常规的方法静态的给一个返回报文,客户端将不会接受,前端就不能正确的显示我们需要的东西。
我们可以使用Fiddler
中的的FiddlerScript
功能实现动态模拟,返回的报文中可以根据URL
的callback
参数的不同,动态返回想要的响应报文,达到需要的效果。
报文分析
如下是Fiddler
抓取的响应报文
ds0000000004418({"status":200,"rs":[{"cmmdtyCode":"000000000133855708","price":"169.00","priceType":"14","singlePrice":"","vipPrice":"","superPrice":"","pricingMode":"","bizCode":"0070062355","vendorName":"PLAYBOY花花公子内衣旗舰店","govPrice":"","type":"2","subCode":"","invStatus":"1","balanceStartTime":"","balanceEndTime":"","locatCode":"0001","stdLocatCode":"","plantCode":"ZE99","chargePlantCode":"","cityFrom":"","arrivalDate":"","purchaseFlag":"5","vendorType":"2","supplierCode":"0070062355","commondityTry":"","reservationType":"","reservationPrice":"","subscribeType":"","subscribePrice":"","collection":"","visited":"","sellingPoint":"","promoTypes":[],"promotionList":[{"type":"4","simple":"每338-169","full":"每338.00元减169.00元","giftList":[]}],"imageUrl":"","patternCss":"","text":"","energySubsidy":"","feature":"0","priceDifference":"","jdPrice":"","jdPriceUpdateTime":"","snPrice":"478.00","refPrice":"","discount":"3.5","originalPrice":"478.00","oversea":"0","shoppingCart":"1","bigPromotion":"0","storeStock":"","distance":"","storeStockName":"","prototype":"","prototypeStoreName":"","prototypeDistance":"","explosion":[{"imageUrl":"http://image.suning.cn/uimg/pcms/label10/207304954913795723821280_39.png","patternCss":"1","text":"","labelPlaceArea":"1111"}],"subCodeImageVersion":"","directoryIds":"361003:233003:340560","pinPrice":"","promotionLable":"","promotionColor":"","promotionLable2":"","promotionColor2":"","purchase":"","replacementRisk":"","minimumSale":"","suningLogistics":"","marketVipPriceType":"","pgActionId":"","pgNum":"","featureService":"","freightInsurance":"","salesVolume":"","goodShop":"","publicWelfare":"","excellentGoods":"","excellentGoodsText":"","shoppingAllowance":"","book":"","book2":"","newArrival":"","supernewArrival":"","freeInterest":"","dr":{},"rq":{},"categoryName":"","goodsIndex":"","qualityInspection":"","jsdflg":"","marketingEventTracking":"14","actype":"14","existFlag":"","biuSmartHome":"","factorySend":"","suningcun":"","storeCode":"","serviceType":"","live":"","liveText":"","allowance":""}],"message":null});
根据获取的报文格式可以发现ds随机数字(json格式数据);
这样的数据格式,可以编写简单的脚本,先从请求URL
中截取ds随机数字
,再将其按照格式与构造好的报文内容
拼接好返回。
本例由于有一个callback
参数的回传,并且是要校验,并且每次都是由客户端生成不同的,无法用AutoResponder
功能模拟,使用QuickExec
功能较困难,至少本例是较困难的。
代码
if (oSession.fullUrl.Contains("ds.suning.com/ds/generalForTile/")){
oSession["ui-color"] = "orange";//颜色橙色 高亮显示出来
oSession["ui-bold"]="true";//字体加粗
var requestUrl = oSession.fullUrl;//获取到请求URL [string]
var responseBody = oSession.GetResponseBodyAsString();//获取到响应体[string]
var rep = /ds\d+/ig;//截取URL中的“ds+数字”的正则表达式
var res = rep.exec(requestUrl); //获取"callback="后面的"ds+随机数字" [string]
var fso = new ActiveXObject("Scripting.FileSystemObject");
var f = fso.OpenTextFile('E:\\ds.txt',1,,);//ds.txt需要ANSI编码保存
var data = f.ReadLine();
var responseBodyNew = res + "(" + data+");";//拼接新的返回body
oSession.utilSetResponseBody(responseBodyNew);
}
- 将此代码插入脚本
static function OnBeforeResponse(oSession: Session) {}
方法中 - 前2行将高亮显示我们模拟的报文有没有匹配到,因为可能修改匹配条件
-
var rep = /ds\d+/ig;
这是配置ds随机数字
的正则表达式 -
var f = fso.OpenTextFile('E:\\ds.txt',1,,)
我们需要将实现准备好的报文(此例为JSON格式的数据)存在此文件,注意保存的编码 -
var responseBodyNew = res + "(" + data+");";
拼接新的响应报文
效果
- 可以刷新页面而不用再去修改报文
- 可以修改报文存储文件中的报文字段,保存文件刷新页面立刻生效
- 修改匹配规则可以适配模拟其他的类似Session
改进
- 给功能加一个开关,勾选上
Rules
中对应的选项,才开启模拟。 - 调整代码,当正则匹配结果为空的时候就直接返回实际的结果
public static RulesOption('模拟ds+接口')
var mockDs: boolean = false;
上面2行代码放在Handlers
中,向Fiddler
注册一个 RulesOption
选项。
if (mockDs && oSession.fullUrl.Contains("ds.suning.com/ds/generalForTile/")){
var requestUrl = oSession.fullUrl;//获取到请求URL [string]
var rep = /ds\d+/ig;//截取URL中的“ds+数字”的正则表达式
var res = rep.exec(requestUrl); //获取"callback="后面的"ds+随机数字" [string]
if (res == null){return;} //发现偶尔匹配不到的情况我也不知道为什么判断一下直接忽略再刷新一下看看吧
var responseBody = oSession.GetResponseBodyAsString();//获取到响应体[string]
oSession["ui-color"] = "orange";//颜色橙色 高亮显示出来
oSession["ui-bold"]="true";//字体加粗
var fso = new ActiveXObject("Scripting.FileSystemObject");
var f = fso.OpenTextFile('E:\\ds.txt',1,,);//ds.txt需要ANSI编码保存
var data = f.ReadLine();
var responseBodyNew = res + "(" + data+");";//拼接新的返回body]
//FiddlerObject.alert(responseBodyNew);//需要弹窗显示拼接的新响应体可取消注释
oSession.utilSetResponseBody(responseBodyNew);
}
后话
粗浅经验
有什么建议和问题欢迎留言