Appearance
Koa基础概念
Koa是一个轻量级的Web框架,通过利用async函数和中间件洋葱模型,提供了一种更优雅的方式来构建Web应用和API。理解Koa的基础概念是掌握这个框架的关键。
上下文(Context)对象
Koa将Node.js的request和response对象封装到单独的context对象中,称为ctx。
Context属性
javascript
app.use(async ctx => {
// 请求相关属性
ctx.request // Koa Request对象
ctx.req // Node.js原生request对象
ctx.method // HTTP方法 (GET, POST, PUT, DELETE等)
ctx.url // 完整URL
ctx.path // 路径部分
ctx.query // 查询参数对象
ctx.params // 路由参数
ctx.headers // 请求头对象
// 响应相关属性
ctx.response // Koa Response对象
ctx.res // Node.js原生response对象
ctx.body // 响应体
ctx.status // 响应状态码
ctx.type // 响应内容类型
ctx.length // 响应长度
});
Context方法
javascript
app.use(async ctx => {
// 设置响应
ctx.body = 'Hello World'; // 设置响应体
ctx.status = 200; // 设置状态码
ctx.set('X-Custom-Header', 'value'); // 设置响应头
ctx.redirect('/new-url'); // 重定向
ctx.throw(400, 'Bad Request'); // 抛出错误
});
中间件(Middleware)
Koa的中间件使用async/await函数,形成了独特的洋葱模型:
javascript
// 洋葱模型示例
app.use(async (ctx, next) => {
console.log('A - 进入'); // 1
await next(); // 调用下一个中间件
console.log('A - 退出'); // 5
});
app.use(async (ctx, next) => {
console.log('B - 进入'); // 2
await next();
console.log('B - 退出'); // 4
});
app.use(async ctx => {
console.log('C - 处理'); // 3
ctx.body = 'Hello Koa';
});
中间件执行顺序
- 每个中间件函数执行到await next()时暂停
- 控制权交给下一个中间件
- 当没有更多中间件时,控制权反向传递
- 继续执行await next()之后的代码
请求(Request)对象
Koa对Node.js的原生request进行了增强:
javascript
app.use(async ctx => {
// 基本信息
ctx.request.method; // HTTP方法
ctx.request.url; // URL
ctx.request.origin; // 协议+主机
ctx.request.href; // 完整URL
// 头信息
ctx.request.header; // 所有请求头
ctx.request.headers; // 所有请求头(别名)
ctx.request.length; // 内容长度
ctx.request.host; // 主机名
ctx.request.hostname; // 不包含端口的主机名
// 查询参数
ctx.request.query; // 解析后的查询参数
ctx.request.querystring; // 原始查询字符串
// 路径信息
ctx.request.path; // 路径
ctx.request.search; // 查询字符串(包含?)
// 类型检查
ctx.request.is('text/html'); // 检查内容类型
ctx.request.accepts('html'); // 检查接受的类型
ctx.request.acceptsCharsets('utf-8'); // 检查接受的字符集
ctx.request.acceptsEncodings('gzip'); // 检查接受的编码
ctx.request.acceptsLanguages('en-US'); // 检查接受的语言
});
响应(Response)对象
Koa对Node.js的原生response进行了增强:
javascript
app.use(async ctx => {
// 设置响应
ctx.response.body = 'Response'; // 设置响应体
ctx.response.status = 200; // 设置状态码
ctx.response.message = 'OK'; // 设置状态消息
ctx.response.length = 100; // 设置响应长度
// 设置头信息
ctx.response.set('Content-Type', 'text/html');
ctx.response.set({
'X-Custom-Header': 'value',
'Cache-Control': 'no-cache'
});
// 重定向
ctx.response.redirect('/new-path');
ctx.response.redirect('back'); // 重定向回referrer
ctx.response.redirect('https://example.com'); // 外部重定向
// 类型和内容
ctx.response.type = 'json'; // 设置内容类型
ctx.response.lastModified = new Date(); // 设置最后修改时间
ctx.response.etag = '12345'; // 设置ETag
});
Koa的错误处理
Koa提供了层次化的错误处理机制:
javascript
const app = new Koa();
// 全局错误处理
app.on('error', (err, ctx) => {
console.error('Server Error:', err);
ctx.status = 500;
ctx.body = { error: 'Internal Server Error' };
});
// 中间件内错误处理
app.use(async (ctx, next) => {
try {
await next();
} catch (err) {
ctx.status = err.status || 500;
ctx.body = { error: err.message };
console.error(err);
}
});
Koa中间件模式
条件中间件
javascript
const conditionalMiddleware = async (ctx, next) => {
if (ctx.path.startsWith('/api')) {
// 只对API路径应用此中间件
console.log('API request');
}
await next();
};
app.use(conditionalMiddleware);
参数化中间件
javascript
const createLogger = (prefix) => {
return async (ctx, next) => {
console.log(`${prefix}: ${ctx.method} ${ctx.path}`);
await next();
};
};
app.use(createLogger('[LOG]'));
应用(Application)对象
Koa应用对象是整个应用的入口:
javascript
const app = new Koa();
// 应用配置
app.proxy = true; // 信任代理头
app.subdomainOffset = 2; // 子域名偏移量
app.env = process.env.NODE_ENV || 'development'; // 环境
// 中间件注册
app.use(middleware);
// 服务器启动
const server = app.listen(3000, () => {
console.log('Server running on port 3000');
});
// 事件监听
app.on('error', (err) => {
console.error('Application error:', err);
});
app.on('close', () => {
console.log('Server closed');
});
Koa与Express的比较
| 特性 | Koa | Express |
|---|---|---|
| 异步处理 | 原生支持async/await | 主要使用回调 |
| 中间件模型 | 洋葱模型 | 线性模型 |
| 核心大小 | 更小 | 较大 |
| 上下文 | 统一的ctx对象 | 分离的req/res |
| 错误处理 | 更好 | 基础 |
洋葱模型详解
javascript
// 示例:洋葱模型的完整执行流程
const app = new Koa();
app.use(async (ctx, next) => {
const start = Date.now();
console.log('1. 开始处理请求');
await next(); // 暂停并等待下游中间件完成
const ms = Date.now() - start;
console.log(`5. 请求处理完成, 耗时 ${ms}ms`);
ctx.set('X-Response-Time', `${ms}ms`);
});
app.use(async (ctx, next) => {
console.log('2. 记录请求信息');
await next();
console.log('4. 记录响应信息');
});
app.use(async ctx => {
console.log('3. 处理业务逻辑');
ctx.body = 'Hello Koa!';
});
这些基础概念构成了Koa框架的核心,为后续学习中间件系统、路由管理等高级特性打下了坚实基础.