一.说明
1.说明
官方文档:https://github.com/alibaba/anyproxy/blob/master/docs/cn/src_doc.md
AnyProxy 是阿里巴巴基于 Node.js 开发的一款开源代理服务器,代理是什么大家都懂,而除代理之外,由于支持自定义rules,可修改request和resposne,因此在很多场景下如mock数据,模拟接口慢查,阻止304,调试时后端不支持跨域头Access-Control-Allow-*的时候都非常有用。(本篇着重介绍下代理和mock功能)

2.特性
优点:
- 支持修改request和response
- 支持注入js
- 支持中间人代理,具备web界面过滤请求,抓包,数据支持保存事后分析
- 开放式api可二次开发
缺点:
- 许久未更新
- 文档或案例难找
- 基于node的代理性能略差
3.安装
1).安装node
安装node https://nodejs.org/en/download/ 找对应系统安装
安装后打开cmd或者终端,输入node -v

再试试npm

出现以上表示安装成功
2).安装anyproxy
全局安装
1 | npm install -g anyproxy |
3).启动
输入anyproxy

可以看到web界面监听在8002端口,http服务代理在8001端口,可以打开127.0.0.1:8002看一下web界面。

4.常用指令
1 | 启动(默认代理监听8001端口,web服务在8002端口,默认不解析https端口) |
**
**
5.外部api
1 | //模块介绍,摘要 |
**
**
二.代理功能
1.PC
说代理,少不了https,一步到位吧,先生成https证书。
1 | anyproxy-ca |
然后会在当前目录的 .anyproxy/certificates/rootCA.crt下生成证书,是一个隐藏目录。
如我的电脑在/Users/ryan执行的anyproxy-ca,生成了/Users/ryan/.anyproxy/certificates/rootCA.crt证书。
双击去安装。

启动并监听https
1 | anyproxy -i |

修改网络配置,设置代理为本机的8001端口。(这步不细说了,都是老司机了)
先访问127.0.0.1:8002,再访问百度随便搜索个啥。


简单过滤下,可以看到访问百度搜索的接口是https协议,可以看到请求参数和返回值。
2.移动端
移动端的也比较简单,在统一局域网下手机代理设置为电脑ip的8001端口即可。
如需https,先在电脑上打开127.0.0.1:8002页面,可以看到左侧菜单栏有个RootCA,点击他。
(不要直接扫语雀这里的,自己电脑上要生成自己的然后手机上安装对应的证书)

后面就不用我多说了吧?跟fidder或charles一样安装证书就好了,关于ios11或者安卓7及以上版本抓包的方法请参考 https://xcz.yuque.com/shswyy/autotest/xlfh4s
3.过滤
页面上很显眼的标识了filter–过滤。

一条规则写一行,如果是多行,每一行将作为独立的过滤规则,结果集取的是过滤规则的并集,所有的过滤都将先从URL开始。
三.mock(推荐)
为什么要mock?
mock的重要性就不提了,其实charles也具备mock功能,甚至你随便用一个能提供web服务的框架不管是java也好,python也好,都可以当作mock服务器,但操作上来说还是繁琐了些。
如果是很多人长期使用的情况下,那作为一项公共服务,不断去开发维护还说得过去,否则就有点本末倒置。
对我来说,业务上要用到mock的场景不多,但真有什么问题,也比较麻烦,比如依赖的第三方查询接口,测试环境一般不稳定,挂了后面的流程我就没法走下去。
又例如列表想看多数据的分页加载情况,造数据麻烦且有污染,使用mock比较好。
如何mock?实例
常用指令中说了,有一项是-r,可以指定规则文件,需要使用rules文件来进行mock数据的返回。
mock之前,这里业务中解析为例,解析出错,无法匹配,无法进行下一步。

首先看下接口和正常情况下的返回:
接口: http://example.com/api/detail?code=AAAAAAAAAAAAAAAAAA
返回:
1 | {"code":200,"data":{"省略...."},"message":"SUCCESS"} |
接口: http://example.com/list?a=b&c=d
返回:
1 | {"code":200,"data":[{"省略..."},{"省略..."}],"message":"SUCCESS"} |
接口:http://example.com/detail?a=xx
1 | {"code":200,"data":[{"省略..."},{"省略..."}],"message":"SUCCESS"} |
编写rule.js,先试试第一个接口。
1 | module.exports = { |
启动
1 | anyproxy -i -r rule.js |
先用curl试一下

拿到的是规则里写的值。
发现页面上无法解析结果,实际已经走到规则里去里。猜测可能是response有问题,找下其他可用环境的返回response。

发现response headers里东西还挺多,经过尝试,我们需要在返回值的headers里加入Access-Control-Allow-Credentials和Access-Control-Allow-Origin。
修改header内容为
1 | { |
再从页面上解析下vin码,nice。

完整rules.js
1 | module.exports = { |
beforeSendRequest和beforeSendResponse
在说明的图示中可以看到有beforeSendRequest和beforeSendResponse两个方法。字面上意思也很好理解,请求发送前和返回值发送前嘛。其作用分别:
beforeSendRequest:请求发送前,可更改请求(包括参数啊,header啊,地址等),或者直接返回自定义内容给你。
beforeSendResponse:请求发送后将返回值传给发送方之前,可修改response的主体内容,修改返回值的header,状态码,或者直接覆盖response。
PS: 上述的mock例子里,因为明知道这几个接口是挂的,也就无需实际发送请求,那么直接用beforeSendRequest方法返回我自定义的返回值即可。
关于修改request和response的官方的几个例子: https://github.com/alibaba/anyproxy/tree/master/rule_sample
四.更多实例
1).替换请求地址
例如你有多个环境,将a环境的请求 发送给 b环境,再返回给页面
原本只有8条数据

现在有2282条了…

1 | module.exports = { |
requestDetail.requestOptions的其他属性:
protocol: 协议,如http, https
hostname:域名
port:端口
path:路径
method:请求方法
2).模拟延迟
例如延迟10秒再返回
1 | module.exports = { |
3).接口请求失败返回自定义response
有时候不想直接返回自定义,想先去请求原始地址,如果报错了,在用自定义返回值。
为了方便,我直接写一个不存在的地址

1 | module.exports = { |