Skip to content

Instantly share code, notes, and snippets.

@zxhfighter
Created July 17, 2014 04:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zxhfighter/18db3c00d76046810a07 to your computer and use it in GitHub Desktop.
Save zxhfighter/18db3c00d76046810a07 to your computer and use it in GitHub Desktop.
use fiddler to save files automatically

使用Fiddler自动保存文件

背景

先来看个生活中的实际需求:在网上看到美图,想保存下来,你是怎么做的呢?

这还不简单?选中图片-图片另存为-选择文件夹保存不就行了么!

其实大部分人都是这么做的,那有没有更好的办法呢?

想象一下,如果我浏览过该图片后,该图片自动保存到了某个我设置的文件夹,那该有多好啊!

没错,Fiddler可以帮我们做这件事!

Fiddler能够捕获和篡改任何HTTP请求的内容,当然可以在请求前和响应前设置钩子来实现特定功能。

Custom Rules

这些钩子都在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代码,有两个函数OnBeforeRequestOnBeforeResponse值得特别关注。没错,它俩就是两个钩子函数,一个在请求前执行,一个在响应前执行。

我们事先自动存图的功能是在响应前执行(如果是请求前执行,那时候图片都木有,巧妇难为无米之炊呀!),因此我们的存图代码需要写在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);
        }
    }
}

大功告成!

其实不止是图片,任何类型的请求都可以使用该方式进行自动存储,需要更改的只是上述代码中的主域和正则过滤而已。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment