koa2
koa2
koa2 和 express 的区别
- 中间件模型
- 洋葱 vs 线性(栈)
- 会影响响应时机,express 会立即响应,koa2 需要等到中间件执行完毕
- 异步方式,回调 vs 同步
- 异常处理,error-first vs try-catch await
- 代码体积
中间件
示例代码如下:
const Koa = require("koa");
const app = new Koa();
// x-response-time 中间件
app.use(async (ctx, next) => {
console.log("\n开始 x-response-time");
const start = Date.now();
await next(); // 调用下一个中间件:logger(等待下一个异步函数返回)
const ms = Date.now() - start;
ctx.set("X-Response-Time", `${ms}ms`); // 设置响应头
console.log("结束 x-response-time\n");
});
// logger 中间件
app.use(async (ctx, next) => {
console.log("开始 logger");
const start = Date.now();
await next(); // 调用下一个中间件:response(等待下一个异步函数返回)
const ms = Date.now() - start;
console.log(
`\u0020\u0020\u0020\u0020\u0020${ctx.method} ${ctx.url} - ${ms} ms`
); // \u0020 为空格
console.log("结束 logger");
});
// response 中间件
app.use(async (ctx) => {
console.log("开始 response");
ctx.body = "Hello World";
console.log("结束 response");
// 没有更多的中间件执行,堆栈将展开并且每个中间件恢复执行其上游行为
});
app.listen(3000);
console.log("app started at port 3000...");
如果一个中间件 没有调用 await next(),后续的 middleware 将不再执行了。例如,一个检测用户权限的 middleware 可以决定是否继续处理请求,还是直接返回 403 错误
app.use(async (ctx, next) => {
if (await checkUserPermission(ctx)) {
await next();
} else {
ctx.response.status = 403;
}
});
常见中间件实现
koa-cors
const URL = require("url");
module.exports = async function (ctx, next) {
let origin = URL.parse(ctx.origin) || "";
if (origin.protocol && origin.host) {
ctx.set(
"Access-Control-Allow-Origin",
`${origin.protocol}://${origin.host}`
);
ctx.set(
"Access-Control-Allow-Headers",
"X-Requested-With, User-Agent, Referer, Content-Type, Cache-Control, accesstoken"
);
ctx.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
ctx.set("Access-Control-Max-Age", "86400");
ctx.set("Access-Control-Allow-Credentials", "true");
}
if (ctx.methods === "OPTIONS") {
ctx.status = 204;
ctx.body = "";
} else {
await next();
}
};