邂逅Koa

123 阅读3分钟

Koa 是 Express 团队开发的新框架,因为 开发团队认为 Express内置了一系列的中间件导致 Express 过于臃肿

而 Koa 只提供了核心功能,任何通过中间件实现的功能都被抽取为单独的库,可以按需引入

 pnpm install koa

基本使用

如果访问不存在的路由时:

  • Express 返回错误状态码和错误页面
  • Koa 返回错误状态码,响应体为字符串 Not Found

image.png

而对于不支持的方法:

  • Express 返回错误状态码和错误页面

  • Koa 默认返回 404 和 Not Found

    • 若需 Koa 返回 405(Method Not Allowed),需通过路由中间件设置
 import Koa from 'koa'
 ​
 // Express是函数,而 Koa 是类
 // 创建app实例时
 //    Express 是 app = express(),
 //    Koa 是 const app = new Koa()
 const app = new Koa()
 ​
 // 使用中间件
 // Koa 默认只提供通用中间件,不支持 路径中间件 和 路由中间件「 方法中间件 」
 // 参数为 ctx 和 next
 //    + ctx 是上下文对象 「 包含 request 和 response 」
 //    + next 是下一个中间件
 app.use((ctx, next) => {
   // 通过 ctx.body 来返回结果
   
   ctx.body = 'Hello World'
 })
 ​
 // 开启服务器方式 koa和express是一致的
 app.listen(3000, () => {
   console.log('Server is running on port 3000')
 })

上下文对象

 import Koa from 'koa'
 ​
 const app = new Koa()
 ​
 // 请求路径为: http://localhost:3000/user/list?offset=2&limit=30
 app.use((ctx, next) => {
   // 大部分需要通过 request 和 response 来获取的属性 被直接挂载到了 ctx 上
 ​
   // 例如: ctx.href 就是 ctx.request.href 的简写
   console.log(ctx.request.href) // http://localhost:3000/user/list?offset=2&limit=30
   // 例如: ctx.url 就是 ctx.request.url 的简写
   console.log(ctx.request.url) // /user/list?offset=2&limit=30
   // 例如: ctx.path 就是 ctx.request.path 的简写
   console.log(ctx.request.path) // /user/list
 ​
   // 例如: ctx.method 就是 ctx.request.method 的简写
   console.log(ctx.request.method) // GET
   // 例如: ctx.query 就是 ctx.request.query 的简写
   console.log(ctx.request.query) // { offset: '2', limit: '30' }
   // 例如: ctx.params 就是 ctx.request.params 的简写
   console.log(ctx.request.params) // undefined
 ​
   // 例如: ctx.origin 就是 ctx.request.origin 的简写
   console.log(ctx.request.origin) // http://localhost:3000
   // 例如: ctx.protocol 就是 ctx.request.protocol 的简写
   console.log(ctx.request.protocol) // http:
   // 例如: ctx.host 就是 ctx.request.host 的简写
   console.log(ctx.request.host) // localhost:3000
   // 例如: ctx.hostname 就是 ctx.request.hostname 的简写
   console.log(ctx.request.hostname) // localhost
 ​
   // 例如: ctx.header 就是 ctx.request.header 的简写
   console.log(ctx.request.header) // 一个对象结构数据
 ​
   // 这里的 ctx.body 就是 ctx.response.body 的简写
   // 指代的就是响应头,相对于的 请求体只能通过 ctx.request.body 来获取
   ctx.body = 'Hello World'
 })
 ​
 app.listen(3000)
 import Koa from 'koa'
 ​
 const app = new Koa()
 ​
 const server = app.listen(3000)
 ​
 // 获取端口号、协议族、地址等信息
 // 他们是通过服务器实例的address方法获取,而是通过上下文对象获取
 console.log(server.address())
 import Koa from 'koa'
 ​
 const app = new Koa()
 ​
 app.use((ctx, next) => {
   // Koa 底层 也是基于 http模块的 createServer 创建的
   // 所以 ctx.req 和 ctx.res 就是 http 模块的 request 和 response
   console.log(ctx.req, ctx.res)
 ​
   // 这是 Koa 的 request 和 response, 是基于 ctx.req 和 ctx.res 进行的二次封装得到的对象
   // 例如: Node.js 的 res 有 end() 方法,但 Koa 的 ctx.response 没有直接提供 end(),
   // 因为 Koa 更推荐用 ctx.body 来设置响应内容。
   console.log(ctx.request, ctx.response)
 ​
   ctx.body = 'Hello World'
 })
 ​
 app.listen(3000)

中间件

 import Koa from 'koa'
 ​
 const app = new Koa()
 ​
 // Koa默认值支持 通用中间件
 // 不支持 一次注册多个中间件,路由中间件和路径中间件
 app.use((ctx, next) => {
   console.log('中间件1')
   next()
 })
 ​
 app.use((ctx, next) => {
   console.log('中间件2')
   next()
 })
 ​
 app.use((ctx, next) => {
   console.log('中间件3')
   ctx.body = 'Hello World'
 })
 ​
 /*
   请求后,控制台输出
   中间件1
   中间件2
   中间件3
 ​
   请求后,浏览器输出
   Hello World
 */
 ​
 const server = app.listen(3000)
 import Koa from 'koa'
 ​
 const app = new Koa()
 ​
 // 和 Express 一样,use方法返回的是app对象,所以可以链式调用
 app.use((ctx, next) => {
   console.log('中间件1')
   next()
 }).use((ctx, next) => {
   console.log('中间件2')
   next()
 }).use((ctx, next) => {
   console.log('中间件3')
   ctx.body = 'Hello World'
 })
 ​
 /*
   请求后,控制台输出
   中间件1
   中间件2
   中间件3
 ​
   请求后,浏览器输出
   Hello World
 */
 ​
 const server = app.listen(3000)