Koa框架的使用

前言

Koa 是 Express 原班团队打造的下一代 Node.js Web 框架,核心仅1600+行代码,轻量简洁,原生支持 async/await,异步处理能力远优于 Express。

Koa 不内置路由、参数解析、静态文件等功能,全部依靠第三方中间件按需引入,自由度极高。本文整合基础使用、路由、参数解析、文件上传、静态服务、错误处理、洋葱模型、Express 对比,可直接当作开发查阅文档。

一、Koa 快速入门

1. 安装与基础服务搭建

安装依赖

复制代码
npm install koa

最简服务示例

js 复制代码
// app.js
const Koa = require('koa')
// 创建Koa实例
const app = new Koa()

// 注册中间件,参数 ctx(上下文)、next(放行函数)
app.use(async (ctx, next) => {
  console.log('进入中间件')
  await next() // 执行下一个中间件
  console.log('离开中间件')
})

// 响应数据
app.use(ctx => {
  // ctx.body 等价于 ctx.response.body,简化写法
  ctx.body = 'Hello Koa'
})

// 监听端口
app.listen(8000, () => {
  console.log('服务启动:http://localhost:8000')
})

核心概念说明

  1. ctx 上下文对象
    Koa 将原生 reqres 封装到 ctx,一次请求共用一个 ctx:
    • ctx.request:原生请求对象
    • ctx.response:原生响应对象
    • 简写:ctx.body = ctx.response.bodyctx.path = ctx.request.path
  1. next()
    放行函数,调用后执行后续中间件;配合 await 实现洋葱模型异步流程。

二、路由处理(@koa/router)

Koa 无内置路由,需安装第三方 @koa/router 区分请求路径与请求方法。

1. 安装

bash 复制代码
npm install @koa/router

2. 基础路由示例

js 复制代码
const Koa = require('koa')
const Router = require('@koa/router')
const app = new Koa()

// 创建路由实例,prefix统一路由前缀
const userRouter = new Router({ prefix: '/users' })

// GET 请求
userRouter.get('/', ctx => {
  ctx.body = '用户列表'
})

// POST 请求,创建资源状态码201
userRouter.post('/', ctx => {
  ctx.status = 201
  ctx.body = '创建用户成功'
})

// 动态路径参数 /users/100
userRouter.get('/:id', ctx => {
  // ctx.params 获取动态参数
  ctx.body = `当前用户ID:${ctx.params.id}`
})

// 注册路由中间件
app.use(userRouter.routes())
// 自动处理非法请求方法(405/501)
app.use(userRouter.allowedMethods())

app.listen(8000)

allowedMethods 作用

  • 接口只实现 GET,客户端发起 PUT/DELETE:返回 405 Method Not Allowed
  • 客户端发起非常规请求(COPY/LINK):返回 501 Not Implemented

三、四种请求参数解析

1. URL 查询参数 query(?name=xxx)

地址:http://localhost:8000/login?username=张三&age=18

js 复制代码
app.use(ctx => {
  // ctx.query 自动解析查询字符串为对象
  console.log(ctx.query.username, ctx.query.age)
  ctx.body = ctx.query
})

2. 动态路径参数 params(/user/:id)

上文路由已演示,ctx.params.xxx 获取。

3. JSON / x-www-form-urlencoded 请求体(koa-bodyparser)

原生 Koa 无法解析 POST 请求体,安装 koa-bodyparser 解析 json、表单编码。

安装

复制代码
npm install koa-bodyparser

使用代码

js 复制代码
const Koa = require('koa')
const bodyParser = require('koa-bodyparser')
const app = new Koa()

// 注册解析中间件
app.use(bodyParser())

app.post('/login', ctx => {
  // ctx.request.body 获取请求体
  const { username, password } = ctx.request.body
  ctx.body = { username, password }
})

4. form-data 文件/表单上传(koa-multer)

bodyparser 无法解析 form-data,使用 koa-multer,支持普通表单+文件上传。

安装

复制代码
npm install koa-multer

1)普通form-data表单

js 复制代码
const multer = require('koa-multer')
// 接收全部表单字段
const upload = multer()
app.use(upload.any())

app.post('/form', ctx => {
  // 普通表单数据存在 ctx.req.body
  console.log(ctx.req.body)
  ctx.body = ctx.req.body
})

2)文件上传(保存到本地)

js 复制代码
const multer = require('koa-multer')
const path = require('path')

// 配置文件存储位置与文件名
const storage = multer.diskStorage({
  // 文件存放目录
  destination: (req, file, cb) => cb(null, './uploads'),
  // 自定义文件名:时间戳+原后缀
  filename: (req, file, cb) => {
    const ext = path.extname(file.originalname)
    cb(null, Date.now() + ext)
  }
})
const upload = multer({ storage })

// single('avatar') 接收单文件,表单字段名avatar
app.post('/upload', upload.single('avatar'), ctx => {
  // 文件信息在 ctx.req.file
  ctx.body = {
    msg: '上传成功',
    fileInfo: ctx.req.file
  }
})

四、静态资源服务器(koa-static)

托管前端打包文件、图片、css/js 静态资源。

安装

arduino 复制代码
npm install koa-static

示例代码

js 复制代码
const Koa = require('koa')
const static = require('koa-static')
const app = new Koa()

// 托管当前目录下build文件夹,访问地址直接读取文件
app.use(static('./build'))

app.listen(8000, () => {
  console.log('静态服务器启动')
})

访问 http://localhost:8000/index.html 自动读取 build 下的 index.html。

五、响应数据与状态码

1. ctx.body 支持所有类型

js 复制代码
// 字符串
ctx.body = '文本内容'
// 对象/数组(自动转JSON)
ctx.body = { name: '小明', age: 20 }
ctx.body = [1, 2, 3]
// 空响应
ctx.body = null

2. 自定义状态码

js 复制代码
// 资源创建成功
ctx.status = 201
// 无内容
ctx.status = 204
// 客户端错误
ctx.status = 400
// 接口不存在
ctx.status = 404

六、全局错误统一处理

通过 Koa 内置事件监听捕获全局异常,统一返回错误格式。

js 复制代码
const Koa = require('koa')
const app = new Koa()

// 业务中间件主动抛出错误
app.use(async ctx => {
  try {
    throw new Error('服务器内部异常')
  } catch (err)
    // 手动触发error事件
    ctx.app.emit('error', err, ctx)
  }
})

// 全局错误监听
app.on('error', (err, ctx) => {
  console.error('错误日志:', err.message)
  ctx.status = 500
  ctx.body = {
    code: 500,
    msg: err.message
  }
})

app.listen(8000)

七、Koa 核心机制:洋葱模型

执行规则

中间件按照先进后出执行,像剥洋葱:

  1. 请求从上到下依次执行中间件 next() 前代码
  2. 所有中间件执行完毕后,从下往上执行 next() 后代码

示例代码直观演示

js 复制代码
const Koa = require('koa')
const app = new Koa()

app.use(async (ctx, next) => {
  console.log('中间件1:进入')
  await next()
  console.log('中间件1:离开')
})

app.use(async (ctx, next) => {
  console.log('中间件2:进入')
  await next()
  console.log('中间件2:离开')
})

app.use(ctx => {
  console.log('路由处理')
  ctx.body = 'ok'
})

app.listen(8000)

输出顺序

复制代码
中间件1:进入
中间件2:进入
路由处理
中间件2:离开
中间件1:离开

优势:异步代码配合 await 执行顺序完全可控,解决 Express 异步中间件执行混乱问题。

八、Koa vs Express 核心区别

对比维度 Express Koa2
架构 大而全,内置路由、静态服务 极简内核,所有功能依赖第三方中间件
异步处理 回调函数,异步流程难控制 原生 async/await,洋葱模型流程清晰
请求响应 分开 req / res 统一封装 ctx 上下文
中间件机制 线性流水模型 洋葱模型(先进后出)
内置API 提供 app.get / app.post 路由 无内置路由,必须使用 koa-router

九、完整项目基础模板(可直接复制使用)

js 复制代码
const Koa = require('koa')
const Router = require('@koa/router')
const bodyParser = require('koa-bodyparser')
const static = require('koa-static')
const multer = require('koa-multer')

// 初始化
const app = new Koa()
const router = new Router({ prefix: '/api' })
const upload = multer({ dest: './uploads' })

// 全局中间件
app.use(bodyParser())
app.use(static('./static'))

// 业务接口
router.get('/user', ctx => {
  ctx.body = { code: 200, data: { name: '测试用户' } }
})
router.post('/login', ctx => {
  const data = ctx.request.body
  ctx.body = { code: 200, data }
})
router.post('/upload', upload.single('file'), ctx => {
  ctx.body = { code: 200, msg: '上传成功', file: ctx.req.file }
})

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

// 全局错误处理
app.on('error', (err, ctx) => {
  ctx.status = 500
  ctx.body = { code: 500, msg: err.message }
})

// 启动服务
app.listen(8000, () => {
  console.log('Koa服务运行在 8000 端口')
})

总结

  1. Koa 核心:ctx 上下文 + next() 洋葱中间件模型;
  2. 路由、参数解析、静态资源、文件上传全部依赖第三方中间件;
  3. 原生支持 async/await,异步代码比 Express 更易维护;
  4. 开发固定流程:初始化Koa实例 → 注册全局中间件 → 编写路由 → 全局错误捕获 → 监听端口。
相关推荐
luckdewei2 小时前
那个用 passlib 做认证的新同事,上线第一天就把用户密码写进了日志
后端
ping某4 小时前
为什么 Nginx 明明监听了 80,转发后端时却用了 4xxxx 端口?
后端·nginx
JustHappy4 小时前
我汇总了身边朋友的经历才发现,其实第一份实习是最难找的......
前端·后端·面试
uhakadotcom4 小时前
在python 的 工程化架构中 ,什么是 薄包装器层?
后端·面试·github
用户1474853079748 小时前
CodeX使用Skill生成游戏美术和音乐资源,一分钟入门
后端
Melody1238 小时前
用 abort 中断 AI 流式请求,我之前做错了
后端
onething3659 小时前
Spring Boot + Spring AI 从入门到实战:7天转型计划 Day 5 —— SSE 流式输出 + 打字机效果
人工智能·后端·全栈
一个做软件开发的牛马9 小时前
MyBatis-Plus 从零实战:完整搭建可运行 Demo,BaseMapper 零 SQL、Wrapper 条件构造、分页插件与代码生成器详解
java·后端
码事漫谈9 小时前
AI 编程的「三体」架构:OpenSpec + Superpowers + GStack 如何让一个开发者撑起整个研发团队
后端