Koa笔记 02:常用中间件

Posted Naisu Xu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Koa笔记 02:常用中间件相关的知识,希望对你有一定的参考价值。

目的

前面的文章 《Koa笔记 01:基础入门》 中对Koa做了个基础的介绍,Koa是个 HTTP中间件框架 ,本身并没有提供很多真正业务处理的功能,需要搭配各种中间件来实现,这篇文章选一些常见的中间件进行介绍。

基础说明

Koa的一些热门的中间件可以在这里找到 https://github.com/koajs/koa/wiki ,也可以在 https://www.npmjs.com/ 中通过关键词搜索,比如 koa websocket

需要注意的是Koa目前大版本到了Koa2,和版本1有较大的变化,中间件使用上要注意版本问题。

Koa的中间件都是一些函数,通过 Koa对象的 use() 方法来注册使用, use() 方法注册使用的先后顺序会影响一个HTTP请求中中间件调用的先后顺序,所以使用 中间件的先后顺序非常重要,接近入口或是出口的中间件需要放在前面 ,比如下面示例:

const Koa = require('koa');
const logger = require('koa-logger');
const helmet = require('koa-helmet');
const Router = require('@koa/router');
const serve = require('koa-static');
const conditional = require('koa-conditional-get');
const etag = require('koa-etag');
const compress = require('koa-compress');

const app = new Koa();
const router = new Router();

app.use(logger()); // 收到请求和发送响应时打印日志,在收发最两头处理

app.use(helmet()); // 处理一些安全性相关的HTTP头,在收到请求时处理

app.use(conditional()); // 缓存处理,在收到请求时处理
app.use(etag());

app.use(compress({br: false})); // 响应数据压缩,在进行应答时处理

app.use(router.routes()); // 路由处理,通常主要工作在此

app.use(serve(__dirname + '/static/', { maxage: 600000 })); // 文件服务,通常放在最后

app.listen(3000);

// 上面代码中完整的中间件顺序如下
// logger -> helmet -> conditional -> etag -> compress -> router -> serve -> router -> compress -> etag -> conditional -> helmet -> logger

// 有些中间件只在请求或响应阶段处理事务,所以实际的流程可能如下
// logger -> helmet -> conditional -> etag -> router -> serve -> compress -> etag -> conditional -> logger

// 实际上还会根据情况不同流程也会不一样,比如如果请求头部有安全问题那流程可能就是下面这样的
// logger -> helmet -> logger

安全防护

koa-helmet 这个中间件用来处理一些安全性相关的HTTP头,可以提高应用程序的安全性。

项目地址:https://github.com/venables/koa-helmet

使用 npm i koa-helmet 进行安装,当前版本为 6.1.0 。当前版本总共提供11项安全方面保护,使用方式如下:

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

app.use(helmet()); // 启用所有安全保护功能

URL路由

URL路由是HTTP服务器最基础的功能需求,Koa中比较热门的中间件有下面两个:

@koa/router 项目地址:https://github.com/koajs/router
koa-route 项目地址:https://github.com/koajs/route

这里主要介绍下前者 @koa/router ,这个中间件源自于 koa-router(https://github.com/ZijianHe/koa-router)。

使用 npm i @koa/router 进行安装,当前版本为 10.1.1 。下面是个简单的使用演示:

const Koa = require('koa');
const Router = require('@koa/router');

const app = new Koa();
const router = new Router();

// GET /a
router.get('/a', (ctx, next) => {
    ctx.body = 'Hello Koa';
});

// POST /b
router.post('/b', (ctx, next) => {
    ctx.body = 'Hello Naisu';
});

app.use(router.routes()); // 启用路由

// 如果使用了不支持的方法访问响应头会返回 405 Method Not Allowed 和 Allow 字段
app.use(router.allowedMethods()); 

app.listen(3000);


上面演示中用到了 GETPOST 方法,此外还支持 PUTDELETErouter.del())方法,另外可以用 router.all() 来接收所有方法的请求。

上述添加url和回调函数的方法都可以填入多个回调函数(其实就相当于多个中间件),比如下面演示:

@koa/router 可以使用 redirect() 方法进行url重定向,比如下面演示:

@koa/router 支持动态路径,比如下面演示:

@koa/router 支持嵌套使用,比如下面演示:

body处理

body部分内容处理是HTTP服务器最基础的功能需求,Koa中比较热门的中间件有下面两个:

koa-body 项目地址:https://github.com/koajs/koa-body
koa-bodyparser 项目地址:https://github.com/koajs/bodyparser

这里主要介绍下前者 koa-body 。

使用 npm install koa-body 进行安装,当前版本为 4.2.0

Koa默认的Request是没有body对象的,用了 koa-body 之后就有body对象了:

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

app.use(koaBody());
app.use(ctx => {
    console.log(ctx.request.body);
});

app.listen(3000);

当然一般来说 POST 、 PUT 这些方法的 Request 中才会有 body 内容,所以这个中间件通常会结合上面的路由中间件来使用,下面是个简单的演示:

上面演示中可以看到对于 x-www-form-urlencoded 和 json 类型的body数据,该中间件默认会将其转换为JS对象。

koa-body 支持接收客户端上传的文件(file uploads),使能 multipart/form-data 格式消息体接收后 使用 ctx.request.files 即可获取,比如下面演示:

默认情况下接收的文件会存放在系统临时目录中(os.tmpDir())。

上面演示中设置了 multipart 选项参数,除了这个 koa-body 还有很多选项可以设置,主要是下面这些:

选项类型说明默认值
patchNodeBoolean将body附加到ctx.reqfalse
patchKoaBoolean将body附加到ctx.requesttrue
jsonLimitString / Integerjson body数据字节数限制1mb
formLimitString / Integerform body数据字节数限制56kb
textLimitString / Integertext body数据字节数限制56kb
encodingString编码格式utf-8
multipartBoolean解析multipart/form-datafalse
urlencodedBoolean解析urlencodedtrue
textBoolean解析texttrue
jsonBoolean解析jsontrue
jsonStrictBooleanjson严格模式true
includeUnparsedBoolean设置为true时可以获得为解析的body数据false
formidableObjectmultipart/form-data相关的更多选项
onErrorFunction错误处理,例如 onError(error, context){ }
strictBoolean启用后不会解析GET/HEAD/DELETE方法的bodytrue
parsedMethodsString[]要处理解析body的方法[‘POST’, ‘PUT’, ‘PATCH’]

上面的 formidable 对象的可设置选项如下:

选项类型说明默认值
maxFieldsInteger字段数量限制1000
maxFieldsSizeInteger字段总字节数限制(文件除外)2mb
uploadDirString文件接收目录os.tmpDir()
keepExtensionsBoolean保留文件原始扩展名false
hashString如果要计算问价hash,可以设置为sha1或md5false
multiplesBoolean多文件上传true
onFileBeginFunction开始接收文件事件,onFileBegin(formName, file){ }
https://github.com/node-formidable/formidable#filebegin

静态文件

静态文件服务是HTTP服务器最基础的功能需求,Koa中比较热门的中间件主要是 koa-static

项目地址:https://github.com/koajs/static

使用 npm install koa-static 进行安装,当前版本为 5.0.0 ,使用方法如下:

const serve = require('koa-static');

app.use(serve(root, opts)); // root是静态文件所在目录,opts是可用选项

可用选项如下:

选项说明默认值
maxage设置max-age值,单位为毫秒0
hidden传输隐藏文件false
index默认文件index.html
defer如果设置为true,则将在next()返回后才发送文件
gzip提供.gz文件支持true
brotli提供.br文件支持true
setHeaders用户自定义响应头
extensions可设置文件扩展名字符串数组,当url没有扩展名时将从这里尝试false

下面是个简单的演示:

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

app.use(serve(__dirname + '/static/', { maxage: 600000 }));

app.listen(3000);

koa-static 是基于 koa-send 的,所以更多内容也可以参考 koa-send :https://github.com/koajs/send

缓存处理

当用户端请求资源时通常会在客户端本地或者网络节点中生成缓存,当客户端再起请求该资源是服务器可以通过一定的处理来判断资源是否更新,需要重新发送资源还是客户端可以使用缓存的资源。使用缓存可以减小网络带宽和服务器的压力。

在Koa中缓存处理比较热门的是使用 koa-conditional-getkoa-etag 两个中间件,两者结合使用。

koa-conditional-get 项目地址:https://github.com/koajs/conditional-get
使用 npm install koa-conditional-get 进行安装,当前版本为 3.0.0

koa-etag 项目地址:https://github.com/koajs/etag
使用 npm install koa-etag 进行安装,当前版本为 4.0.0

使用方法如下:

const conditional = require('koa-conditional-get');
const etag = require('koa-etag');

app.use(conditional());
app.use(etag());

下面是个简单的演示:

数据压缩

通常HTTP通讯中对于大块的数据会压缩有进行传输,以减小网络压力、节省浏览。Koa比较热门的中间件是 Koa Compress

项目地址:https://github.com/koajs/compress

使用 npm install koa-compress 进行安装,当前版本为 5.1.0 ,使用方法如下:

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

app.use(compress({
    threshold: 2048, // 响应大于2048字节才压缩,默认为1024(1kb)
    br: false // 禁用br压缩方式,这样接下来会使用gzip
}));

下面是个简单的演示:

模板引擎

模板引擎是HTTP服务器中经常用到的功能,Koa中比较热门的中间件有下面两个:

koa-ejs 项目地址:https://github.com/koajs/ejs
koa-views 项目地址:https://github.com/queckezz/koa-views

认证与会话

身份认证与会话管理也是Web中常用的功能,这类技术方案很多,下面是一些使用比较多的技术中比较热门的中间件:

koa-jwt 项目地址:https://github.com/koajs/jwt
koa-basic-auth 项目地址:https://github.com/koajs/basic-auth
koa-session 项目地址:https://github.com/koajs/session
koa-passport 项目地址:https://github.com/rkusa/koa-passport

运行日志

koa-logger 这个中间件可以打印输出HTTP请求与响应相关信息。

项目地址:https://github.com/koajs/logger

使用 npm install koa-logger 进行安装,当前版本为 3.2.1 ,使用方法与演示如下:

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

app.use(logger()); // 该中间件使用时通常放在最前面

总结

这篇文章介绍了Koa中间件查询使用的一些基础内容,并介绍了一些常用的中间件。有这些内容基本上就可以用来开发基本的HTTP服务器应用了。

以上是关于Koa笔记 02:常用中间件的主要内容,如果未能解决你的问题,请参考以下文章

KOA学习笔记

koa 常用中间件

koa 学习笔记

Koa.js笔记

koa 核心拓展——中间件机制

傻瓜式解读koa中间件处理模块koa-compose