MKOA内置两个对Request.js进行代理函数,方便处理一般API请求。(学习:koa-grace项目)
### proxy——数据代理
修改config.js文件,开启代理助手。
~~~
,apiProxy_open:true
,apiProxy_prefix:{} //API调用配置{servicName:prefix}
~~~
支持两种数据代理场景:
1. 单纯的数据代理,任意请求到后端接口,然后返回json数据(也包括文件流请求到后端,后端返回json数据);
2. 文件代理,请求后端接口,返回一个文件(例如验证码图片);
下面逐一介绍两种代理模式的使用方法。
#### 1、 数据代理
数据代理可以在控制器中使用`this.proxy`方法:
```
this.proxy(object|string,[opt])
```
##### 使用方法
`this.proxy` 方法返回的是一个Promise,所以这里你可以根据当前Controller的类型使用`async/await`或者`Generator`实现异步并发。例如:
**async/await:**
```
exports.demo = async function () {
await this.proxy({ /* ... */ })
}
```
**Generator:**
```
exports.demo = function * () {
yield this.proxy({ /* ... */ })
}
```
为了使语法更简便,可以在执行`this.proxy`之后,直接在上下文中的`backData`字段中获取到数据。例如:
```
exports.demo = async function () {
await this.proxy({
userInfo:'github:post:user/login/oauth/access_token?client_id=****',
otherInfo:'github:other/info?test=test',
})
console.log(this.backData);
/**
* {
* userInfo : {...},
* otherInfo : {...}
* }
*/
}
```
`Generator`方法亦然。
此外,如果要获取proxy的请求头信息,你可以在proxy方法返回的内容中获取到,例如:
```javascript
exports.demo = async function (){
let res = await this.proxy({
userInfo:'github:post:user/login/oauth/access_token?client_id=****',
otherInfo:'github:other/info?test=test',
});
console.log(res);
/**
* {
* userInfo : {
* statusCode: {...} // 返回http status code
* request: {...} // 请求体
* headers: {...} // 响应头信息
* body: {...} // 未处理的response body
* },
* otherInfo : {...}
* }
*/
}
```
##### 使用场景一:多个数据请求的代理
可以发现,上文的案例就是多个数据同时请求的代理方案,这里也就是**异步并发**获取数据的实现。使用`this.proxy`方法实现多个数据异步并发请求非常简单:
```javascript
exports.demo = async function (){
await this.proxy({
userInfo:'github:post:user/login/oauth/access_token?client_id=****',
otherInfo:'github:other/info?test=test',
});
console.log(this.backData);
/**
* {
* userInfo : {...},
* otherInfo : {...}
* }
*/
}
```
然后,proxy的结果会默认注入到上下文的`this.backData`对象中。
##### 使用场景二:单个数据请求的代理
如果只是为了实现一个接口请求代理,可以这么写:
```javascript
exports.demo = async function (){
await this.proxy('github:post:user/login/oauth/access_token?client_id=****');
}
//post不指定前置配置及自定义参数
exports.demo = async function (){
await this.proxy(':post:user/login/oauth/access_token?client_id=****',{form: {code: 123}});
}
```
这样proxy请求返回的数据体会直接赋值给`this.body`,也就是将这个请求直接返回给客户端。
##### 说明
`github:post:user/login/oauth/access_token?client_id=****`说明如下:
* `github`: 为在`config.js`的 `apiProxy_prefix` 对象中进行配置;
* `post` : 为数据代理请求的请求方法,该参数可以不传,默认为`get`
* `path`: 后面请求路径中的query参数会覆盖当前页面的请求参数(this.query),将query一同传到请求的接口
* 你也可以写完整的路径:`{userInfo:'https://api.github.com/user/login?test=test'}`
另外,`this.proxy`的形参说明如下:
| 参数名 | 类型 | 默认 | 说明|
| --- | --- | --- |
| `dest` | `Object` | `this.backData` | 指定接收数据的对象,默认为`this.backData` |
| `conf` | `Obejct` | `{}` | this.proxy使用[Request.js](https://github.com/request/request)实现,此为传给request的重置配置(你可以在这里设置接口超时时间:`conf: { timeout: 25000 }`)|
|`form` | `Object` | `{}` | 指定post方法的post数据,默认为当前页面的post数据,这里的数据content-type会根据当前请求的类型指定|
| `headers` | `Object` | `{}` | 指定当前请求的headers|
关于this.proxy方法还有很多有趣的细节,推荐有兴趣的同学看源码:https://github.com/xiongwilee/koa-grace/middleware/proxy
#### 2、 文件代理
文件代理可以在控制器中使用`this.fetch`方法:
```
this.fetch(string)
```
文件请求代理也很简单,比如如果需要从github代理一个图片请求返回到浏览器中,参考:http://feclub.cn/user/avatar?img=https://avatars.githubusercontent.com/u/1962352?v=3 , 或者要使用导出文件的功能:
```javascript
exports.avatar = async function (){
await this.fetch(imgUrl);
}
```
这里需要注意的是:**在this.fetch方法之后会直接结束response, 不会再往其他中间件执行**。