先来看个生活中的实际需求:在网上看到美图,想保存下来,你是怎么做的呢?
这还不简单?选中图片-图片另存为-选择文件夹保存不就行了么!
其实大部分人都是这么做的,那有没有更好的办法呢?
想象一下,如果我浏览过该图片后,该图片自动保存到了某个我设置的文件夹,那该有多好啊!
没错,Fiddler可以帮我们做这件事!
Fiddler能够捕获和篡改任何HTTP请求的内容,当然可以在请求前和响应前设置钩子来实现特定功能。
这些钩子都在Fiddler的自定义脚本中定义,启动Fiddler,然后选择Rules -> Custom Rules
,会用记事本打开一个CustomRules.js文件,所有的玄机都隐藏在该文件中。
该文件是一个古老的JScript文件,JScript的语法尽管看起来有些奇怪,其实它是符合ECMAScript规范的,所以熟悉JavaScript的人阅读起来不会太困难。
当然,我们只想在需要的时候才把Fiddler捕获的特定图片保存下来,因此我们需要一个开关来控制。
我们在CustomRules.js文件发现了这样一段代码:
public static RulesOption("Hide 304s")
BindPref("fiddlerscript.rules.Hide304s")
var m_Hide304s: boolean = false;
其实上面这段代码提供了菜单Rules -> Hide 304s
的开关控制功能,我们可以依葫芦画瓢,写上这么两行。
// Data Storage
public static RulesOption("Data Storage")
var m_DataStorage: boolean = false;
保存CustomRules.js后,马上会在Rules
菜单下看到Data Storage
选项,勾上后,变量m_DataStorage
就设置为true,反之false。
这样我们可以只有在Rules -> Data Storage
选项被勾上后才进行自动存储。
查看CustomRules.js代码,有两个函数OnBeforeRequest
、OnBeforeResponse
值得特别关注。没错,它俩就是两个钩子函数,一个在请求前执行,一个在响应前执行。
我们事先自动存图的功能是在响应前执行(如果是请求前执行,那时候图片都木有,巧妇难为无米之炊呀!),因此我们的存图代码需要写在OnBeforeResponse
钩子函数中。
// 存储路径
static var dataPath: String = 'D:/images/';
// ...省略代码
// 响应前的钩子函数
static function OnBeforeResponse(oSession: Session) {
if (m_Hide304s && oSession.responseCode == 304) {
oSession["ui-hide"] = "true";
}
// 请求正则,.jpg结尾
var reg = /\.jpg(\?|$)/i;
// 提取路径的正则
var pathReg = /(.+?\.jpg)(\?|$)/i;
// 最终保存路径
var savePath: String = "";
// 如果打开了自动存储的开关
if (m_DataStorage) {
// 对URL进行一些主域和正则过滤,这里可以根据需求自定义
// 这里只存储来自xx.baidu.com的正常jpg文件(没有挂掉)
if (dataPath
&& ("xx.baidu.com" === oSession.host)
&& (oSession.oResponse.headers.HTTPResponseCode == 200)
&& reg.test(oSession.PathAndQuery)
) {
savePath = dataPath + oSession.PathAndQuery.match(pathReg)[1];
FiddlerObject.log('data storage had saved: ' + savePath);
oSession.SaveResponseBody(savePath);
}
}
}
大功告成!
其实不止是图片,任何类型的请求都可以使用该方式进行自动存储,需要更改的只是上述代码中的主域和正则过滤而已。