Appearance
Koa
介绍
自行百度
安装
npm i koa
最基本的启动服务
javascript
const Koa = require('koa');
const app = new Koa();
app.use((ctx,next)=>{
ctx.body = "hello"; // ctx.body用于将内容返回给客户端
next();
});
app.use((ctx)=>{
ctx.body += " world";
});
app.listen(8008,()=>{
console.log("Server is running on http://localhost:8008");
});
洋葱圈模型
先看例子
javascript
app.use((ctx,next)=>{
console.log('1');
next();
console.log('2');
});
app.use((ctx,next)=>{
console.log('3');
next();
console.log('4');
});
app.use((ctx)=>{
console.log('5');
});
// 输出顺序是 1 3 5 4 2
记住两条规则:
1、遇到next,先执行下一个
2、执行完毕后(指遇到路由),一步步退回,继续执行
注意这里第二条规则。假设我们有如案例所示的三段,前两个是中间件,那么这里的"一步步退回继续执行"指的是,先退回到第二个中间件,把里面剩下的代码跑完,然后退回第一个中间件,把剩下的代码跑完。
把发起请求到路由响应看做洋葱的外皮和内核的话,中间件就相当于是一层层的洋葱,执行顺序就是一层层逼近路由,再一步步退回,所以叫洋葱圈模型。
ctx 上下文
ctx是http上下文,是http请求+http响应
ctx.request: http请求
ctx.response: http响应
平时会看到ctx.body或ctx.url等方法,实际上是koa做了一层代理。真正的函数其实是ctx.response.body,ctx.request.url。
koa-router
koa没有提供内置的组件,所以我们想要处理路由需要使用koa-router。
首先要安装
npm i koa-router
javascript
// 导入
const Router = require('koa-router');
// 实例化对象
const router = new Router();
router.get('/', (ctx)=>{
ctx.body="主页";
});
app.use(router.routes());
app.use(router.allowedMethods()); // 对于除GET/POST外的请求方式需要加上这一行才能处理
获取请求参数
获取get的请求参数(或者可以说,是获取url中明文写好的参数)
javascript
// 静态参数
// url/user?name=Tom&age=18
router.get('/user', (ctx)=>{
console.log(ctx.query); // ctx.query接收键值对参数
});
// 动态参数
router.get('/news/:page', (ctx)=>{
console.log(ctx.params.page); // ctx.params接收动态参数
});
获取表单之类的,包裹在请求体中的数据,koa本身是没有提供方法的。我们需要下载处理用的模块。
官方推荐使用两个:
- koa-bodyparser
- koa-body
我们使用koa-body。首先安装:
npm i koa-body
javascript
// 导入
const KoaBody = require('koa-body');
// 注册
app.use(KoaBody());
// 使用
router.post('/login', (ctx)=>{
ctx.body = JSON.stringify(ctx.request.body);
});
错误处理
使用ctx.throw对问题进行抛出。
javascript
router.get('/news/:id', (ctx)=>{
console.log(ctx.params);
// 如果没有用ctx.body返回内容,默认会返回404错误
// ctx.throw(自定义或规定的校验码, '自定义的返回内容')
// 想返回json形式的返回内容需要用JSON.stringify("自定义内容")
// =================================
// 由于throw返回的是字符串格式的错误信息,我们想要返回json格式的信息时需要自定义监听事件
ctx.app.emit('error',{code:500,message: "错误"}, ctx); // 抛出error错误
})
// 使用on监听事件,当node检测到错误就会执行
app.on('error', (err, ctx)=>{
ctx.body = err;
});
最佳方式:使用koa-json-error。先安装
npm i koa-json-error
javascript
// 导入
const error = require('koa-json-error');
// 注册
app.use(error());
// 使用
router.post('/login', (ctx)=>{
ctx.throw(422,"错误")
});
// 默认会返回一个带有三属性的对象。我们可以自定义
自定义返回内容
javascript
// 在注册的时候添加代码
app.use(error({
format: (err)=>{
return {code: err.status, message: err.message, result: err.result}
},
postFormat: (err,obj)=>{
const {result, ...rest} = obj;
return process.env.NODE_END == 'production' ? rest : obj;
}
}))
// 这里的format是返回格式,postFormat用来控制实际的返回
// process.env.NODE_END的设置请查看node章节
// {result, ...rest}对此有疑问查看ES6的相关内容,三个点叫做展开运算符