dalao-proxy
Version:
An expandable HTTP proxy based on the plug-in system for frontend developers with request caching request mock and development!
612 lines (503 loc) • 19.7 kB
Markdown
# Dalao-proxy
基于插件系统的可扩展HTTP代理,用于前端开发人员请求缓存、数据模拟和页面开发!
> 一行代码就可以启动服务器! 日常开发中比 `webpack-dev-server` 代理更轻便、更方便。
[](https://www.npmjs.com/package/dalao-proxy)
[](https://github.com/CalvinVon/dalao-proxy)
[](https://packagequality.com/#?package=dalao-proxy)

[English Doc](https://github.com/CalvinVon/dalao-proxy/blob/master/README.md)
|
[中文文档](https://github.com/CalvinVon/dalao-proxy/blob/master/README_CN.md)
## 特性
- HTTP 代理
- HTTP 捕获
- 请求模拟
- 通过灵活配置自动缓存请求
- 自动生成配置文件
- 配置文件更改时自动重启
- 支持多环境快速自由切换
- 可扩展和插件架构的系统

# 目录
- [起步](#起步)
- [安装](#安装)
- [配置](#配置)
- [启动代理](#启动代理)
- [快乐程序员](#快乐程序员)
- [命令行](#命令行)
- [开始缓存请求响应](#开始缓存请求响应)
- [举个栗子](#举个栗子)
- [`Never Read Cache` 模式](#Never-Read-Cache-模式)
- [`Read Cache` 模式](#Read-Cache-模式)
- [开始模拟请求数据](#开始模拟请求数据)
- [文档](#文档)
- [详细配置](#详细配置)
- [选项 `host`](#选项-host)
- [选项 `watch`](#选项-watch)
- [选项 `cache`](#选项-cache)
- [选项 `headers`](#选项-headers)
- [选项 `cacheContentType`](#选项-cacheContentType)
- [选项 `cacheMaxAge`](#选项-cacheMaxAge)
- [选项 `responseFilter`](#选项-responseFilter)
- [选项 `proxyTable`](#选项-proxyTable)
- [`route` 配置](#route-配置)
- [`route`选项 `pathRewrite`](#route-选项-pathRewrite)
- [插件系统[Beta版]](#插件系统Beta版)
- [安装插件](#安装插件)
- [全局安装](#全局安装)
- [局部安装](#局部安装)
- [可用的插件](#可用的插件)
- [生命周期钩子](#生命周期钩子)
- [beforeCreate](#beforeCreate)
- [onRequest](#onRequest)
- [onRouteMatch](#onRouteMatch)
- [beforeProxy](#beforeProxy)
- [afterProxy](#afterProxy)
# 起步
## 安装
```bash
$ npm i dalao-proxy -g
```
## 配置
默认配置文件将会生成在 `dalao.config.json`.
```bash
# 初始化工具会帮助你生成定制的配置文件
$ dalao-proxy init
# 直接生成默认配置文件
$ dalao-proxy init -y
```
## 启动代理
```bash
# dalao 将会读取默认配置文件
$ dalao-proxy start
# 定制命令行选项
dalao-proxy start -wc --config ./dalao.config.json
```
启动选项
```
Options:
-C, --config [filepath] 使用定制的配置文件
-w, --watch 配置文件更新时自动重启
-P, --port [port] 定制代理监听端口
-H, --host [hostname] 定制代理监听host
-t, --target [proxyTarget] 代理目标地址
-c, --cache 开启请求缓存
-i, --logger 开启日志输出
-h, --help 输出帮助信息
```
🎉 恭喜, 你的代理服务器已经启动, 现在你也拥有了自己的 *dalao*!
## 快乐程序员
每次修改配置文件,`dalao` 都会自动重启并输出提示。
[返回目录](#目录)
# 命令行
```bash
$ dalao-proxy --help
Usage: dalao-proxy [options] [command]
Options:
-V, --version 输出版本号
-h, --help 输出帮助信息
Commands:
start [options] 自动检测配置 & 启动代理服务器
init [options] 在当前文件夹中创建一个配置文件
mock [options] <method> 创建一个 json 格式的 mock 文件
clean [options] 清空所有缓存文件
add-plugin [options] <pluginName> 全局添加插件
```
# 开始缓存请求响应
1. 将选项 `cache` 设置为 `true`
1. 设置适当的 `cacheContentType`, `cacheMaxAge`,`responseFilter` 选项值
当这三个字段满足某些条件时,请求响应将作为缓存文件保存在指定的`cacheDirname`文件夹中。
## 举个栗子
以下是服务器响应数据的简单示例
```bash
// 发送请求
POST /api/list HTTP/1.1
...
// 请求响应
connection: keep-alive
content-encoding: gzip
content-type: application/json; charset=UTF-8
date: Fri, 19 Apr 2019 08:35:42 GMT
server: nginx/1.10.3 (Ubuntu)
transfer-encoding: chunked
vary: Accept-Encoding
// 响应数据
{
"status": 1,
"data": {
"list": [
{ "id": 1, "name": "dalao" },
{ "id": 2, "name": "proxy" }
],
"total": 2
}
}
```
配置应该是这样的:
```js
"cache": true,
"cacheContentType": ["application/json"],
"responseFilter": ["status", 1],
```
## `Never Read Cache` 模式
如果你只想把真实的响应缓存起来,并对请求代理没有任何影响的话。
> **建议** 当要求返回真实的、高精度的响应数据时。
> **场景** 当后端服务在开发期间崩溃时,你可以快速切换到 [`Read Cache` 模式](#Read-Cache-模式) 以 **创建一个不依赖于后端的简单“后台”服务**。
> 想要在此模式时,**为某个接口单独返回缓存/模拟文件时**,你可以选择删除缓存在JSON(JS)文件中的 `CACHE_TIME` 字段,而不是反复修改配置来切换模式,后者将会频繁重启服务。(更新于 **v0.8.3**)
将选项 `cacheMaxAge` 设置成 *Never Read Cache* 模式
```js
"cacheMaxAge": ["s", 0]
```
## `Read Cache` 模式
当你准备开发前端页面或需要 [开始 MOCK 请求](#开始-MOCK-请求) 时,或者要获取更多变的数据时。
> `dalao-proxy` 会先尝试查找缓存/模拟文件,若没有找到时再返回真实的请求响应。
> **建议:** 更简单的方法是删除缓存在JSON(JS)文件中的 `CACHE_TIME` 字段。(更新于 **v0.8.3**)
将选项 `cacheMaxAge` 设置为 *Read Cache* 模式。 [选项 `cacheMaxAge`](#Option-cacheMaxAge)
```js
// 设置永久请求缓存
"cacheMaxAge": ["s", "*"]
"cacheMaxAge": ["second", "*"]
// set certain expire time request cache (5 min)
"cacheMaxAge": ["m", 5]
"cacheMaxAge": ["minute", 5]
```
[返回目录](#目录)
# 开始模拟请求数据
> **v0.9.0更新** 现在, `dalao-proxy` 支持JS类型的缓存文件,因此,你可以引用任何库来模拟你的数据. 例如使用 [`Mock.js`](https://github.com/nuysoft/Mock/wiki/Getting-Started)
输入 `dalao-proxy mock <HTTP method>` 和要模拟的 HTTP 请求方法
```bash
# dalao-proxy mock [options] <method>
$ dalao-proxy mock post
> Request url: /api/list
Mock file created in /home/$(USER)/$(CWD)/.dalao-cache/GET_api_get.json
# 传入`--js`参数来使用 js模式的缓存文件
$ dalao-proxy mock post --js
> Request url: /api/list
Mock file created in /home/$(USER)/$(CWD)/.dalao-cache/GET_api_get.js
```
将一些模拟数据放入`GET_api_get.json`文件或在js文件中执行任何操作,然后您可以访问`/api/list`以获取模拟数据。
```json
{
"data": {
"list": ["mock", "data"]
},
"code": 200
}
```
```js
const mockjs = require('mockjs');
const list = Mock.mock({
'list|1-10': [{
'id|+1': 1
}]
});
module.exports = {
data: list,
code: 200
};
```
[返回目录](#目录)
---
# 文档
## 详细配置
启动时,`dalao-proxy`将在当前工作目录中查找并读取配置文件。
默认的配置文件名是 `dalao.config.json`
```js
{
// 配置文件文件名
"configFileName": "dalao.config.json",
// 请求缓存文件存储文件夹名称
"cacheDirname": ".dalao-cache",
// 是否监听配置文件更改并自动重新加载
"watch": true,
// 代理服务器 host
"host": "localhost",
// 代理服务器端口号
"port": 8000,
// 代理目标(通用设置)
"target": "target.example.com",
// 是否启用代理请求缓存(通用设置)
"cache": false,
// 设置要缓存请求响应的内容类型(通用设置)
"cacheContentType": [
"application/json"
],
// 设置缓存文件的最长有效时间
"cacheMaxAge": [
"second",
0
],
// 设置请求返回体过滤器
"responseFilter": [],
// 开启日志
"logger": false,
// 显示调试信息
"debug": false,
// 自定义响应头
"headers": {},
// 代理路由规则表
"proxyTable": {
// 匹配规则
"/": {
"path": "/"
}
},
// 插件列表
"plugins": []
}
```
### 选项 `host`
- 类型: **string**
> 当配置为 `0.0.0.0` 时,局域网内其他设备也可以访问,本机使用`localhost`访问。
### 选项 `watch`
- 类型: **boolean**
- 默认值: `true`
配置文件更改时启用代理服务器自动重新加载。
### 选项 `headers`
- 类型: **Object**
添加自定义的 **请求头** 或者 **响应头** ([更新于**v0.9.11**](./CHANGELOG.md#0911-2019-10-10)).
例子:
```json
{
"headers": {
"request": {
"Token": "THIS-IS-YOUR-FAKE-TOKEN"
},
"response": {
"Authorization": "THIS-IS-YOUR-FAKE-AUTHORIZATION"
}
}
}
```
或者默认这样来 **单独设置响应头** (向后兼容).
```json
{
"headers": {
"Authorization": "THIS-IS-YOUR-FAKE-AUTHORIZATION"
}
}
```
### 选项 `cache`
- 类型: **boolean**
- 默认值: `true`
响应满足[一些条件](#开始缓存请求响应)时启用请求缓存。
> 当请求从缓存文件返回时,会在响应标头中添加额外字段 `X-Cache-Request`。
### 选项 `cacheContentType`
- *前提条件: 当 `cache` 选项为 `true`*
- 类型: **Array**
- 默认值: `['application/json']`
按响应内容类型筛选,当至少有一个项匹配时缓存请求响应。
*支持 `正则` 表达式*
### 选项 `cacheMaxAge`
- *前提条件: 当 `cache` 选项为 `true`*
- 类型: **Array**
- cacheMaxAge[0]: 设置缓存过期时间单位(支持简写 `d`, `day`, `days`)。
- cacheMaxAge[1]: 设置缓存过期时间数值
- 当值为 `0` 时, `dalao-proxy` 将 **永远不会** 尝试读取缓存文件 (但仍然缓存请求响应)。
- 当值为特殊值 `'*'` 时, 表示缓存文件将 **永不过期**, `dalao-proxy` 先尝试读取并返回缓存文件,若没有找到再返回真实的请求响应。
- 默认值: `['second', 0]`
设置缓存文件的的到期时间(最长有效时间)。
> `X-Cache-Expire-Time` 和 `X-Cache-Rest-Time` 字段将会被包含在响应标头中。
### 选项 `responseFilter`
- *前提条件: 当 `cache` 选项为 `true`*
- 类型: **Array**
- responseFilter[0]: 设置用于判断是否缓存的响应体字段
- responseFilter[1]: 设置该字段的有效值
- 默认值: `['code', 200]`
设置通过响应数据判断是否缓存。 *不是通过 HTTP 状态码判断*
### 选项 `plugins`
- 类型: **Array**
设置使用插件的列表 *npm 包名*。
你将会需要添加插件来扩展 `dalao-proxy` 的能力。请参阅 [插件](#插件) 部分.
### 选项 `proxyTable`
- 类型: **Object**
- 默认值: `{ "/": { "path": "/" } }`
代理 [route](#route-配置) 配置集合。
### `route` 配置
> 填写完路由之后,所有配置字段均可省略不填
```js
{
// 代理目标路径
// 默认: `/`
"path": "/api/your/target",
// 代理目标
// 继承于通用配置项 `target`
"target": "http://your.target.com",
// 代理目标路径重写
"pathRewrite": {
"^/api": "/api/v1"
},
// 路由自定义配置
// 继承于通用配置项 `cache`
"cache": true,
// 继承于通用配置项 `cacheContentType`
"cacheContentType": ["json"],
// 继承于通用配置项 `cacheMaxAge`
"cacheMaxAge": ["year", 365],
// 继承于通用配置项 `responseFilter`
"responseFilter": ["code", 200],
}
```
#### Route 选项 `pathRewrite`
使用`正则表达式`匹配目标路径,并替换为重写值。
例:
```js
"pathRewrite": {
"^/api": ""
}
```
`"/api/user/list"` 将被替换为 `"/user/list"`
[返回目录](#目录)
---
# 插件系统[Beta版]
`Dalao-proxy` 现在通过使用选项 [`plugins`](#Option-plugins) 来支持使用自定义插件。
> 注意,重新安装 `dalao-proxy` 将导致全局安装的插件失效(局部安装不受影响),你需要重新全局安装需要的插件。
## 安装插件
### 全局安装
```bash
# 全局安装
$ dalao-proxy add-plugin <plugin name>
# 全局卸载
$ dalao-proxy add-plugin -d <plugin name>
```
### 局部安装
```bash
$ npm install -D dalao-proxy
$ npm install -D <插件名称>
```
生成配置文件
```bash
$ npx dalao-proxy init
```
在配置文件的 `plugins` 选项中添加
```json
{
"plugins": [
"<插件名称>"
]
}
```
然后在 package.json 中添加命令
```json
{
"scripts": {
"proxy": "dalao-proxy start"
}
}
```
你也可以自己开发插件来扩展 `dalao-proxy` 的行为能力。
## 可用的插件
- [*内建*] [**check-version**](https://github.com/CalvinVon/dalao-proxy/tree/master/src/plugin/check-version)
该插件将自动检查 `dalao-proxy` 的最新版本。
- [*内建*] [**proxy-cache**](https://github.com/CalvinVon/dalao-proxy/tree/master/src/plugin/proxy-cache)
该插件完成了很棒的请求缓存和模拟工作.
- [**@calvin_von/proxy-plugin-monitor**](https://github.com/CalvinVon/dalao-proxy/tree/master/packages/%40calvin_von/proxy-plugin-monitor) 用于请求监控的插件
> 查看代理的请求在 dalao-proxy 内部匹配的规则和具体请求的位置。
- [*新发布*] [**@calvin_von/proxy-plugin-redirect**](https://github.com/CalvinVon/dalao-proxy/tree/master/packages/%40calvin_von/proxy-plugin-redirect) 用于请求重定向的插件
> 用于在本地调试线上(前端)代码的插件。
## 生命周期钩子
`Dalao-proxy` 提供了不同代理周期之间的生命周期钩子.
> 注意:给出的 `context` 参数里的所有数据*均非只读*,你可以随意修改和覆盖这些值,但是要注意各个插件和核心代码之间的配合。
> **最佳实践**:每一个插件都在 `context` 参数下生产自己的上下文数据,根据插件执行的顺序来适当修改 `dalao-proxy` 及其插件的行为。
### `beforeCreate`
> 你可以在这里做一些根据配置文件的定义的初始化操作。
- 类型: `Function`
- 参数
- `context`
- `context.config`: 解析过的配置文件对象。
- 详情:
在创建代理服务器之前调用。
### `onRequest`
- 类型: `Function`
- 参数
- `context`
- `context.config`: 解析过的配置文件对象。
- `context.request`: 代理服务器接收到的请求。 `http.IncomingMessage` 的实例
- `context.response`: 代理服务器需要返回的响应对象。 `http.ServerResponse` 的实例
- `next`
- 类型: `Function`
- 参数: `error`/`interruptMessage`
- 如果 `error` 参数被传入, 此次请求将由于抛出错误而导致被中断。
- 如果一个 `string` 类型的参数传入, 它将被视为`PluginInterrupt`而不会抛出错误
`next`函数必须被调用,以进入下一个周期。
- 详情:
代理服务器接收到请求时调用。
### `onRouteMatch`
- 类型: `Function`
- 参数
- `context`
- `context.config`: 解析过的配置文件对。
- `context.request`: 代理服务器接收到的请求。
- `context.response`: 代理服务器需要返回的响应对象。
- `context.matched`
- `path`: 匹配到的请求 path。
- `route`: 匹配的路由对象。
- `notFound`: 是否匹配到给定的 proxyTable。
- `next`
- 类型: `Function`
- 参数: `error`/`interruptMessage`
- 如果 `error` 参数被传入, 此次请求将由于抛出错误而导致被中断。
- If a `string` param passed in, 它将被视为`PluginInterrupt`而不会抛出错误
`next`函数必须被调用,以进入下一个周期。
- 详情:
请求URL与给定`proxyTable`规则匹配时调用。
### `beforeProxy`
- 类型: `Function`
- 参数
- `context`
- `context.config`: 解析过的配置文件对。
- `context.request`: 代理服务器接收到的请求。
- `context.response`: 代理服务器需要返回的响应对象。
- `context.matched`
- `path`: 匹配到的请求 path。
- `route`: 匹配的路由对象。
- `context.proxy`
- `uri`: 转换过后的 URI 地址。
- `route`: 匹配的路由对象。
- `next`
- 类型: `Function`
- 参数: `error`/`interruptMessage`
- 如果 `error` 参数被传入, 此次请求将由于抛出错误而导致被中断。
- If a `string` param passed in, 它将被视为`PluginInterrupt`而不会抛出错误
`next`函数必须被调用,以进入下一个周期。
- 详情:
在 `dalao-proxy` 开始发送代理请求之前调用。
### `afterProxy`
- 类型: `Function`
- 参数
- `context`
- `context.config`: 解析过的配置文件对。
- `context.request`: 代理服务器接收到的请求。
- `context.response`: 代理服务器需要返回的响应对象。
- `context.matched`
- `path`: 匹配到的请求 path。
- `route`: 匹配的路由对象。
- `context.proxy`
- `uri`: 转换过后的 URI 地址。
- `route`: 匹配的路由对象。
- `request`: 代理请求对象。 `request.Request`的实例。 在 [Github 上查看 request/request](https://github.com/request/request#streaming)
- `response`: 代理响应对象。 `request.Response` 的实例。
- `context.data`
- `error`: 代理请求中出错的错误对象。 `Error` 的实例
- `request`
- `rawBody`: 请求体的原始数据。
- `body`: 解析后的请求体数据。
- `query`: 解析后的请求查询参数。
- `type`: 请求的内容类型。
- `response`
- `rawBody`: 代理响应体的原始数据。
- `body`: 解析后的代理响应体的数据。
- `type`: 代理响应的内容类型。
- `size`: 代理响应的内容大小。
- `encode`: 代理响应的内容类型。
- `next`
- 类型: `Function`
- 参数: `error`/`interruptMessage`
- 如果 `error` 参数被传入, 此次请求将由于抛出错误而导致被中断。
- If a `string` param passed in, 它将被视为`PluginInterrupt`而不会抛出错误
`next`函数必须被调用,以进入下一个周期。
- 详情:
在 `dalao-proxy` 发送代理请求并解析完所有请求和响应数据后调用。
[返回目录](#目录)
# LICENSE
[MIT LICENSE](https://github.com/CalvinVon/dalao-proxy/blob/master/LICENSE)