Fiddler 调试API基操:转发请求和跨域伪装

Fiddler 调试API基操:转发请求和跨域伪装

zeee 2,713 2020-04-28

简介

在开发接口的过程中, 经常会遇到接口调试不方便的问题, 比如:

  • 前端网站发布在开发环境上, 想要连接本地进行接口调试
  • 对于某些请求, 希望临时返回特定结果
  • 跨域请求调试希望直接通过跨域而不需要修改后端逻辑(或者直接请求第三方的网站调试)

这样的一些需求, 单纯用浏览器调试工具比较难实现. 这时候网络调试神器 Fidder 就该上线了. Fiddler 可以代理监听所有网络请求, 而且可以对网络请求进行断点调试, 重播, 过滤等操作.

另外, Fiddler 支持插件安装以及自定义脚本, 可以让用户按需实现特定需求. 比如上面所提到的需求,就可以通过编写插件或者修改脚本的方式来实现. 下面就简单介绍修改脚本实现方法.

Fiddler 的脚本存放在 CustomRule.js 文件中, 要修改脚本只需要修改这个文件即可, 具体来说:

打开 fiddler > Rules > CustomsizeRules 编辑脚本

虽然是js脚本, 但是里面用到的类库跟C#/TS和相似, 编辑器本身也提供了一定的只能提示, 脚本编写体验还是比较友好的

主要代码是在 Handlers 类中, 这个类里面定义了许多成员和事件方法, 我们便可以在这些事件中添加自定义的逻辑以达到需求. 下面介绍两种:

  • 转发请求并修改部分请求数据
  • 修改响应头已实现(绕过)浏览器的跨域拦截

请求转发

这个需求的原因是, 在工作所开发的项目中, 后端接口添加了权限验证, 需要体统诸如UserId等字段, 但是前端不会直接提供这些数据(只提供一个Token), 所以通过前端调试后端接口就比较麻烦, 所以需要 Fiddler 实现类似这样一个拦截:

  • 把所有发往: oldzeng.com/api/test 的请求全部转发到 localhost:5000 并在请求头添加一定数据

简单方法

如果仅仅是简单的请求转发话不需要写脚本, 直接在 Fiddler 的 AutoResponder 添加一条规则即可. 但这种方法不能修改请求, 无法实现修改请求头的需求, 如图(其中 1 处的 path 为匹配url剩余的字符串):

image-20200428231403043

修改脚本方法

// 在 Handlers 类中添加如下按钮和方法,  一般是在 OnBeforeRequest 前, 这样比较好找
public static RulesOption("本地代理")
var m_poxy: boolean = false;

static function LocalProxy(oSession: Session){
    var api = "oldzeng.com/api/test";
    if(m_poxy && oSession.uriContains(api)){	
        // 转发请求
        oSession.host = "localhost:5000";
        // 修改请求头
        oSession.RequestHeaders.Add("UserId", "ssssssssss");
        oSession.RequestHeaders.Add("UserName", "zeng");
        oSession.RequestHeaders.Add("Email", "me@oldzeng.com");
    }
}

// ...
// 然后在 OnBeforeRequest 方法中调用
LocalProxy(oSession)

跨域支持, 主要是在本地启动前端时解决跨域问题

同理, 拦截特定请求的响应结果, 并修改响应头, 可以绕过浏览器的跨域检查, 已实现跨域请求的需求

// 在 OnBeforeResponse 添加如下选项按钮和方法
public static RulesOption("CORS伪造")
var m_fakecors: boolean = false;
static function FakeCors(oSession: Session){
    if(m_fakecors && (
        oSession.oRequest.headers.HTTPMethod == "OPTIONS" ||
    	oSession.oRequest.headers.Exists("Origin"))){
        
        if(!oSession.oResponse.headers.Exists("Access-Control-Allow-Origin"))
        {
            var requestOrigin = "*";
            if(oSession.oRequest.headers['Origin'] != "")
            {
                requestOrigin = oSession.oRequest.headers['Origin'];
            }
            oSession.oResponse.headers.Add("Access-Control-Allow-Origin", requestOrigin);
        }

        if(!oSession.oResponse.headers.Exists("Access-Control-Allow-Methods"))
            oSession.oResponse.headers.Add("Access-Control-Allow-Methods", "POST, GET, PATCH, PUT,DELETE, OPTIONS");

        if(oSession.oRequest.headers.Exists("Access-Control-Request-Headers"))
        {
            if(!oSession.oResponse.headers.Exists("Access-Control-Allow-Headers"))
                oSession.oResponse.headers.Add(
                    "Access-Control-Allow-Headers"
                    , oSession.oRequest.headers["Access-Control-Request-Headers"]
                    );
        }

        if(!oSession.oResponse.headers.Exists("Access-Control-Max-Age"))
            oSession.oResponse.headers.Add("Access-Control-Max-Age", "1728000");

        if(!oSession.oResponse.headers.Exists("Access-Control-Allow-Credentials"))
            oSession.oResponse.headers.Add("Access-Control-Allow-Credentials", "true");
    }
}
// ...
// 然后在 OnBeforeResponse 方法中调用
FakeCors(oSession);

效果如图: 需要对应的功能, 就在选项上打个勾就可以了.

image-20200428232416208

参考链接


# web