koa2的中间件功能及应用示例


Posted in Javascript onMarch 05, 2020

最近因为开发一个自己的博客网站,学习了koa2的搭建,写了一些自己认为比较重要或需要知道的koa2中间件作用和使用场景。

koa-router

路由中间件

下载

npm i koa-router

使用

普通使用方法

需要注意的是引入的koa-router是一个方法,引入后需要执行这个方法。

const Koa = require('koa'); 
const app = new Koa(); 
const router = require('koa-router')(); 

// 配置路由url 
// 默认url 
router.get('/', async (ctx, next) => { 
 ctx.body = 'Hello World'; 
}); 

// 自定义url 
router.get('/hello/:name', async (ctx, next) => { 
 var name = ctx.params.name; 
 ctx.response.body = \`<h1>Hello, ${name}!</h1>\`; 
}); 

// 注册路由 
app.use(router.routes(), router.allowedMethods());

也可以按需引入并注册路由,可注册多个路由。

不同请求下接收的参数获取

router.get

通过ctx.query获取参数

router.post
通过ctx.request.body获取参数

动态路由 router.get('/:id', func)
通过ctx.params获取参数

遍历注册router

首先引入nodejs中的fs模块,使用fs的readdirSync方法获取到指定目录的所有文件名,遍历引入路由模块并注册。

const fs = require('fs'); 

// fs.readdirSync 获取指定目录下的所有文件名称,遍历引入路由模块并注册 
fs.readdirSync('./routes').forEach(route=> { 
 let api = require(\`./routes/${route}\`); 
 app.use(api.routes(), api.allowedMethods()); 
});

koa-router中的其它api

router.prefix(prefix) 添加url前缀

设置已经初始化的路由器实例的路径前缀

router.prefix('/user'); 
router.post('/login', function(ctx, next) { 
 ... 
}); 

// 实际路径 /user/login

router.use(url|[url1,url2,...], (ctx, next) => {...}) 路由中间件

使用场景:我们通常需要通过验证用户和用户权限来判定用户是否能使用该接口,如果在每个接口都写一次验证非常麻烦且不好维护。这时我们就需要路由中间件先进行验证,再执行下面操作。

router.use的第一个参数为一个路径或者由多个需要使用中间件的路径组成的数组(需要注意的是,如果路由设置了url前缀,需要在设置前缀后注册中间件,参数中的url不需要设置前缀)。

router.use的第二个参数为函数,函数传递ctx和next两个参数,可通过ctx进行权限验证后,判断是否执行next调用接口。这里特别需要注意的是函数使用next的时候需要添加await,如果不添加,在调用接口前,接口就会返回结果,前台则无法获取到数据。

// this is wrong 
 app.use(function (ctx, next) { 
  ctx.set("Access-Control-Allow-Origin", "\*"); 
  next(); 
 }); 
 // this is right 
 app.use(async function (ctx, next) { 
  ctx.set("Access-Control-Allow-Origin", "\*"); 
  await next(); 
 });

koa-bodyparser处理post请求

处理post请求时,我们会遇到一个问题,无论是node的request对象还是koa的request对象,都没办法解析request的body,我们就需要下载并引入一个解析body的中间件koa-bodyparser,koa-bodyparser的具体配置详见下面的说明,这里我们直接放入使用方式。

// 引入路由文件 
 const index = require('./routes/index.js'); 
 const user = require('./routes/user.js'); 

 // 引入解析request.body的中间件 
 const bodyparser = require('koa-bodyparser'); 

 // 注册bodyparser,需要注意,bodyparser的注册一定要在router路由注册之前 
 app.use(bodyparser({ 
  enableTypes:\['json', 'form', 'text'\] 
 })); 

 ... 

 // 注册routes 
 app.use(index.routes(), index.allowedMethods()); 
 app.use(user.routes(), user.allowedMethods());

koa-bodyparser

如上所述,koa-bodyparser用于解析request.body,因为node和koa的request无法解析body。

下载

npm i koa-bodyparser

使用

const bodyparser = require('koa-bodyparser');

在注册运行时,bodyparser方法中可传入对象,作相应配置。

- enableTypes:解析器只在配置了enableTypes时解析请求类型,默认是['json', 'form']。
- encoding:请求编码,默认是utf-8。
- formLimit:urlencoded body的imit如果主体最终大于此限制,则返回一个413错误代码。默认是56 kb。
- jsonLimit:json主体的限制。默认是1 mb。
- textLimit:文本主体的限制。默认是1 mb。
- strict:当设置为true时,JSON解析器将只接受数组和对象。默认是正确的。参见正文中的严格模式。在严格模式下,ctx.request。body总是一个对象(或数组),这避免了很多类型判断。但文本正文总是返回字符串类型。
- detectJSON:自定义json请求检测函数。默认为null。

app.use(bodyparser({ 
 detectJSON: function (ctx) { 
 return /\\.json$/i.test(ctx.path); 
 } 
}));

- extendTypes:支持扩展类型

app.use(bodyparser({ 
   extendTypes: { 
   json: \['application/x-javascript'\] // 解析application/x-javascript 类型 作为JSON字符串 
   } 
  }));

- onerror:支持自定义错误句柄,如果koa-bodyparser抛出一个错误,您可以自定义响应如下:

app.use(bodyparser({ 
   onerror: function (err, ctx) { 
   ctx.throw('body parse error', 422); 
   } 
  }));

- disableBodyParser:可以通过设置ctx动态禁用body解析器。disableBodyParser = true。

app.use(async (ctx, next) => { 
   if (ctx.path === '/disable')     ctx.disableBodyParser = true; 
   await next(); 
  }); 
  app.use(bodyparser());

koa-logger

请求响应监听日志

下载

npm i koa-logger

使用

~~// 引入日志中间件 
const logger = require('koa-logger'); 

// 注册日志中间件 
app.use(logger()); ~~

koa-session

用于Koa的简单会话中间件。默认为基于cookie的会话,并支持外部存储。

session

我们知道,http协议是无状态的,当用户进行登录后,并不会保存账户密码,如果我们需要维持用户的登录状态,就需要使用一些方法。目前主流的用户认证方法有基于token和基于session两种方式。

基于token的认证可以使用koa-jwt中间件,基于session的认证则使用标题的koa-session。

下载

npm i koa-session

使用

app.js 入口文件中注册session

const CONFIG = { 
 key: 'koa:sess', /\*\* (string) cookie key (default is koa:sess) \*/ 
 /\*\* (number || 'session') maxAge in ms (default is 1 days) \*/ 
  // 状态保存最大时间,默认为一天 
 maxAge: 86400000, 
 autoCommit: true, /\*\* (boolean) 自动保存头部 (default true) \*/ 
 overwrite: true, /\*\* (boolean) 能否覆盖 (default true) \*/ 
 httpOnly: true, /\*\* (boolean) httpOnly or not (default true) \*/ 
 signed: true, /\*\* (boolean) signed or not (default true) \*/ 
 /\*\* (boolean) 强制在每个响应上设置会话标识符cookie。过期将重置为原始maxAge,重新设置过期倒计时。 (default is false) \*/ 
 rolling: false, 
 /\*\* (boolean) 当会话快过期时续订会话,这样我们可以始终保持用户登录。(default is false)\*/ 
 renew: false, 
}; 

// 如果你所有都为默认配置,则不需要传递配置参数,app.use(session(app))即可 
app.use(session(sessionConfig, app));

session的使用

注册后可以通过上下文ctx找到session属性,下面代码将用户信息存入session属性中,并创建key和value

user.js

// 用户登录 
static async login(ctx, next) {

const data = ctx.request.body 
const schema = Joi.object().keys({ 
 username: Joi.string().required(), 
 password: Joi.string().required(), 
}) 
let result = Joi.validate(data, schema) 
// 如果有字段类型错误 
if(result.error) { 
 return ctx.response.body = { status: 400, msg: result.error.details}; 
} 
let { username, password } = result.value // 验证过后的数据 
// 查找是否有该用户 
const userInfo = await usersModel.findByName(username) 
// 如果有该用户,继续验证密码是否正确 
if (userInfo) { 
 const userInfo2 = await usersModel.findOne({ username, password }) 
 if (userInfo2) { 
  ctx.response.body = {state: 200, msg: '登录成功'} 
  // 设置session 
  ctx.session.userInfo = userInfo2 
 } else { 
  ctx.response.body = {state: 410, msg: '密码错误'} 
 } 
// 如果没有该用户,返回结果 
} else { 
 ctx.response.body = {state: 410, msg: '该用户不存在'} 
} 
return ctx.response.body 
}

koa-router路由中间件中验证session,这里需要注意的是next()方法前一定要使用await,不然程序不会等待next()方法执行。

export const verifyUser = async (ctx, next) => {

if (ctx.session.userInfo) { 
 await next() 
} else { 
 return ctx.response.body = { state: 401, msg: '无权限访问' } 
} 
}

koa2-cors

用于解决跨域问题

下载

npm install koa2-cors

使用

app.use(cors())

到此这篇关于koa2的中间件功能及应用示例的文章就介绍到这了,更多相关koa2 中间件内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
刷新页面实现方式总结(HTML,ASP,JS)
Nov 13 Javascript
javascript void(0)的妙用
Oct 21 Javascript
关闭ie窗口清除Session的解决方法
Jan 10 Javascript
JS应用正则表达式转换大小写示例
Sep 18 Javascript
jQuery实现3D文字特效的方法
Mar 10 Javascript
基于jQuery实现数字滚动效果
Jan 16 Javascript
Vue.js中extend选项和delimiters选项的比较
Jul 17 Javascript
javaScript实现鼠标在文字上悬浮时弹出悬浮层效果
Apr 12 Javascript
vue.js打包之后可能会遇到的坑!
Jun 03 Javascript
element-ui中的select下拉列表设置默认值方法
Aug 24 Javascript
原生js实现二级联动菜单
Nov 27 Javascript
vue如何批量引入组件、注册和使用详解
May 12 Vue.js
微信小程序利用for循环解决内容变更问题
Mar 05 #Javascript
javascript将16进制的字符串转换为10进制整数hex
Mar 05 #Javascript
js将URL网址转为16进制加密与解密函数
Mar 04 #Javascript
基于node+websocket+html实现腾讯课堂聊天室聊天功能
Mar 04 #Javascript
VUE实现Studio管理后台之鼠标拖放改变窗口大小
Mar 04 #Javascript
微信小程序如何加载数据库真实数据的实现
Mar 04 #Javascript
微信小程序开发搜索功能实现(前端+后端+数据库)
Mar 04 #Javascript
You might like
yii框架中的Url生产问题小结
2012/01/16 PHP
php第一次无法获取cookie问题处理
2014/12/15 PHP
破除网页鼠标右键被禁用的绝招大全
2006/12/27 Javascript
JS 常用校验函数
2009/03/26 Javascript
jQuery checkbox全选/取消全选实现代码
2009/11/14 Javascript
Js中setTimeout()和setInterval() 何时被调用执行的用法
2013/04/12 Javascript
在百度知道团队中快速审批新成员的js脚本
2014/02/02 Javascript
jquery修改网页背景颜色通过css方法实现
2014/06/06 Javascript
JQuery选中checkbox方法代码实例(全选、反选、全不选)
2015/04/27 Javascript
简单介绍JavaScript数据类型之隐式类型转换
2015/12/28 Javascript
jQuery实现图片向左向右切换效果的简单实例
2016/05/18 Javascript
VUE页面中加载外部HTML的示例代码
2017/09/20 Javascript
小程序中this.setData的使用和注意事项
2019/08/28 Javascript
利用d3.js实现蜂巢图表带动画效果
2019/09/03 Javascript
Vue实现购物车实例代码两则
2020/05/30 Javascript
python实现定制交互式命令行的方法
2014/07/03 Python
Python写入数据到MP3文件中的方法
2015/07/10 Python
python安装mysql-python简明笔记(ubuntu环境)
2016/06/25 Python
Python中元组,列表,字典的区别
2017/05/21 Python
matplotlib 纵坐标轴显示数据值的实例
2018/05/25 Python
Python定义一个跨越多行的字符串的多种方法小结
2018/07/19 Python
jupyter notebook oepncv 显示一张图像的实现
2020/04/24 Python
Keras—embedding嵌入层的用法详解
2020/06/10 Python
英国时尚运动品牌的合集:The Sports Edit
2017/12/20 全球购物
Currentbody西班牙:美容仪专家
2019/09/28 全球购物
求职自荐信格式
2013/12/04 职场文书
学校门卫工作职责
2013/12/07 职场文书
应届生自我鉴定
2013/12/11 职场文书
化学教师自荐信范文
2013/12/28 职场文书
饭店工作计划书
2014/01/10 职场文书
留守儿童工作方案
2014/06/02 职场文书
2014年机关党委工作总结
2014/12/11 职场文书
大国崛起日本观后感
2015/06/02 职场文书
2019个人工作计划书的格式及范文!
2019/07/04 职场文书
女性励志书籍推荐
2019/08/19 职场文书
python基础之类属性和实例属性
2021/10/24 Python