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

最近因为开发一个自己的博客网站,学习了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 中间件内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解KOA2如何手写中间件(装饰器模式)

    前言 Koa 2.x 版本是当下最流行的 NodeJS 框架, Koa 2.0 的源码特别精简,不像 Express 封装的功能那么多,所以大部分的功能都是由 Koa 开发团队(同 Express 是一家出品)和社区贡献者针对 Koa 对 NodeJS 的封装特性实现的中间件来提供的,用法非常简单,就是引入中间件,并调用 Koa 的 use 方法使用在对应的位置,这样就可以通过在内部操作 ctx 实现一些功能,我们接下来就讨论常用中间件的实现原理以及我们应该如何开发一个 Koa 中间件供自己和别

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

    最近因为开发一个自己的博客网站,学习了koa2的搭建,写了一些自己认为比较重要或需要知道的koa2中间件作用和使用场景. koa-router 路由中间件 下载 npm i koa-router 使用 普通使用方法 需要注意的是引入的koa-router是一个方法,引入后需要执行这个方法. const Koa = require('koa'); const app = new Koa(); const router = require('koa-router')(); // 配置路由url //

  • 基于对象合并功能的实现示例

    前言 jQuery 中的 $.extend() 是经常使用到工具函数,多用于合并参数(对象),具体用法在这里不过多赘述,可通过传参控制合并过程中是否使用深度拷贝:而ES2015中新增的 Object.assign()方法,也可以实现对象的合并,不过合并过程中使用的是浅拷贝:本文参考了jQuery的extend方法的源码,将自己实现对象合并,即将多个对象的属性复制到目标对象上,若有相同的属性,后面的对象覆盖前面的. 浅拷贝的方式实现对象合并 之前的一篇博文 有专门介绍对象和数组的深浅拷贝,不了解的

  • thinkPHP5框架实现分页查询功能的方法示例

    本文实例讲述了thinkPHP5框架实现分页查询功能的方法.分享给大家供大家参考,具体如下: controller文件内Admin.php <?php namespace app\admin\controller; use think\Controller; use app\admin\model\Admin as AdminModel; //使用分页类 取别名解决类名冲突 class Admin extends Controller{ public function lst(){ /* 分页开

  • Android PC投屏功能实现的示例代码

    本文介绍了Android PC投屏功能实现的示例代码,分享给大家,具体如下: 代码地址 :https://github.com/deepsadness/MediaProjectionDemo 效果预览 投屏效果预览 简单说明: 使用Android MediaProjection Api来完成视频的截图 通过WebSocket进行链接.将图片传递给网页 想法来源 看到vysor,觉得特别好玩,于是就想着自己能不能试着做一个类似的功能出来.搜索了相关实现.发现网上已经有网友针对vysor做了分析.于

  • vue ssr+koa2构建服务端渲染的示例代码

    之前做了活动投放页面在百度.360等渠道投放,采用 koa2 + 模版引擎的方式.发现几个问题 相较于框架开发页面效率较低,维护性差 兼容性问题,在页面中添加埋点后发现有些用户的数据拿不到,排查后发现通过各个渠道过来的用户的设备中仍然包含大量低版本的浏览器. 服务端渲染 服务端渲染和单页面渲染区别 查看下面两张图,可以看到如果是服务端渲染,那么在浏览器中拿到的直接是完整的 html 结构.而单页面是一些 script 标签引入的js文件,最终将虚拟dom去挂在到 #app 容器上. @vue/c

  • 使用PyQt的QLabel组件实现选定目标框功能的方法示例

    问题背景   基于PyQt5开发了一个可以用于目标跟踪的软件,在开发过程中遇到一个问题,就是如何在PyQt5的组件QLable中自主选定目标框,这个在opencv里面有专门的函数完成这个工作:cv2.selectROI(),我的目的就是在QLabel的基础上,实现类似函数cv2.selectROI()的功能,这样在运行程序的过程中,就能在视频框里面直接选取感兴趣区域.直接贴出实现的最终效果: 上图中的红色框框就是在QLabel的基础上实现的功能. 实现思路   具体要实现的功能是,在视频显示区域

  • ThinkPHP5.1验证码功能实现的示例代码

    ۩ 背景 ThinkPHP5.1 已经出现很久了,最近有所接触,下面介绍一下常用的第三方验证码功能的使用. 环境 框架版本: ThinkPHP5.1.2 运行环境: CentOS7.2.phpStudy2017.Nginx ♜ 功能开发 1).引入第三方扩展包 进行 TP5 的开发,Composer 的使用会成为重要技能,以 windows 为例子,输入命令: composer require topthink/think-captcha 完成上述操作,会在以下目录中出现 captcha 的扩展

  • 微信公众号网页分享功能开发的示例代码

    现在每天都可以看到很多微信分享的链接上面有网站或者商家的自定义的分享标题,和分享链接的描述及分享出去的图像,例如下面的分享出去的链接: 上面这个是微信的js-SDK页面分享给微信好友在聊天列表中显示的视觉效果. 微信JS-SDK Demo :这个是微信网页分享出去的标题. 微信JS-SDK,帮助第三方为用户提供更优质的移动web服务:这个是被分享的这个页面的分享描述. 微信图标:这个就是自己网站或者自己自定义的图像. 上面这个是微信官方网页分享出去的定义描述,那么怎样实现自己网站网页的自定义分享

  • Java调用微信支付功能的方法示例代码

    Java 使用微信支付 前言百度搜了一下微信支付,都描述的不太好,于是乎打算自己写一个案例,希望以后拿来直接改造使用. 因为涉及二维码的前端显示,所以有前端的内容 一. 准备工作 所需微信公众号信息配置 APPID:绑定支付的APPID(必须配置) MCHID:商户号(必须配置) KEY:商户支付密钥,参考开户邮件设置(必须配置) APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置) 我这个案例用的是尚硅谷一位老师提供的,这里不方便提供出来,需要大家自己找,或者公司提供 二

  • Android使用Walle实现多渠道打包功能的实现示例

    目录 介绍 使用 对应的属性: 可使用以下变量: 介绍 Walle(瓦力)是Android Signature V2 Scheme签名下的新一代渠道包打包神器. 瓦力通过在Apk中的APK Signature Block区块添加自定义的渠道信息来生成渠道包,从而提高了渠道包生成效率,可以作为单机工具来使用,也可以部署在HTTP服务器上来实时处理渠道包Apk的升级网络请求. 使用 使用Walle生成多渠道的速度是很快的,原来的项目打一个包就需要两分钟多,每次发布打7个包需要十几分钟.用了Walle

随机推荐