前面的文章 《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 -> helmet -> 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()); // 启用所有安全保护功能
需要注意的是 koa-helmet 中的一些项目可能会导致一些限制,比如其中包含 Content-Security-Policy (CSP) 项目,这个会阻止内嵌在html中的js脚本的运行,可能导致一些页面无法正常工作。如果需要在html中内嵌js脚本的话需要禁用此项,所以在使用的时候需要用下面方式:
app.use(helmet({ contentSecurityPolicy: false }));
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);
上面演示中用到了 GET
和 POST
方法,此外还支持 PUT
和 DELETE
(router.del()
)方法,另外可以用 router.all()
来接收所有方法的请求。
上述添加url和回调函数的方法都可以填入多个回调函数(其实就相当于多个中间件),比如下面演示:
@koa/router 可以使用 redirect()
方法进行url重定向,比如下面演示:
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 还有很多选项可以设置,主要是下面这些:
选项 | 类型 | 说明 | 默认值 |
---|---|---|---|
patchNode | Boolean | 将body附加到ctx.req | false |
patchKoa | Boolean | 将body附加到ctx.request | true |
jsonLimit | String / Integer | json body数据字节数限制 | 1mb |
formLimit | String / Integer | form body数据字节数限制 | 56kb |
textLimit | String / Integer | text body数据字节数限制 | 56kb |
encoding | String | 编码格式 | utf-8 |
multipart | Boolean | 解析multipart/form-data | false |
urlencoded | Boolean | 解析urlencoded | true |
text | Boolean | 解析text | true |
json | Boolean | 解析json | true |
jsonStrict | Boolean | json严格模式 | true |
includeUnparsed | Boolean | 设置为true时可以获得未解析的body数据 | false |
formidable | Object | multipart/form-data相关的更多选项 | |
onError | Function | 错误处理,例如 onError(error, context){ } | |
strict | Boolean | 启用后不会解析GET/HEAD/DELETE方法的body | true |
parsedMethods | String[] | 要处理解析body的方法 | [‘POST’, ‘PUT’, ‘PATCH’] |
上面的 formidable
对象的可设置选项如下:
选项 | 类型 | 说明 | 默认值 |
---|---|---|---|
maxFields | Integer | 字段数量限制 | 1000 |
maxFieldsSize | Integer | 字段总字节数限制(文件除外) | 2mb |
uploadDir | String | 文件接收目录 | os.tmpDir() |
keepExtensions | Boolean | 保留文件原始扩展名 | false |
hash | String | 如果要计算问价hash,可以设置为sha1或md5 | false |
multiples | Boolean | 多文件上传 | true |
onFileBegin | Function | 开始接收文件事件,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-get
和 koa-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服务器应用了。