一、基本用法
安装:
npm install --save koa
用 Koa 架设一个 HTTP 服务,在app.js 输入以下内容:
const Koa = require('koa');
const app = new Koa();
app.listen(3000);
运行这个脚本。
node app.js
打开浏览器,访问 http://127.0.0.1:3000 。你会看到页面显示"Not Found",表示没有发现任何内容。这是因为我们并没有告诉 Koa 应该显示什么内容。
二、中间件middleware
app.use() 用来加载中间件。use 里面必须放入函数。基本上,Koa 所有的功能都是通过中间件实现的,每个中间件默认接受两个参数,第一个参数是 Context (ctx)对象,第二个参数是 next (放行函数)函数。只要调用 next 函数,就可以把执行权转交给下一个中间件。
看一下 next 的放行顺序:
const Koa = require('koa');
const app = new Koa();
app.use((ctx,next)=>{
console.log(">>one");
next().then(()=>{console.log("one OK")});
console.log("<<one");
});
app.use((ctx,next)=>{
console.log(">>two");
next().then(()=>{console.log("two OK")});
console.log("<<two");
});
app.use((ctx,next)=>{
console.log(">>three");
console.log("<<three");
});
app.listen(3000);
// ========放行顺序
>>one
>>two
>>three
<<three
<<two
<<one
two OK
one OK
不写 async 的时候 next 是异步的最后执行。
异步中间件:基本上所有的中间件都是同步的,不包含异步操作。如果有异步操作(比如读取数据库),中间件就必须写成 async 函数。
写上 async next 就变成同步执行语句了。
const Koa = require('koa');
const app = new Koa();
app.use(async (ctx,next)=>{
console.log(">>one");
await next().then(()=>{console.log("one OK")});
console.log("<<one");
});
app.use((ctx,next)=>{
console.log(">>two");
next().then(()=>{console.log("two OK")});
console.log("<<two");
});
app.use((ctx,next)=>{
console.log(">>three");
console.log("<<three");
});
app.listen(3000);
// ========放行顺序
>>one
>>two
>>thre
<<thre
<<two
two OK
one OK
<<one
中间件之间的联系:
const Koa = require('koa');
const app = new Koa();
app.use(async (ctx,next)=>{
console.log(1);
await next().then((res)=>{console.log(res)});
});
app.use((ctx,next)=>{
console.log(2);
return 9999;
});
app.listen(3000);
输出结果:1 2 9999
,第二个中间件可以返回内容给第一个中间件。
三、返回给用户的内容
使用 app.use 方法加载 ctx.response.body(或 ctx.body) 返回内容。ctx.response 代表 HTTP Response。同样地,ctx.request 代表 HTTP Request。
const Koa = require('koa');
const app = new Koa();
app.use(function(ctx){
ctx.response.body = 'Hello World';
});
app.listen(3000);
Koa 默认的返回类型是text/plain,如果想返回其他类型的内容,可以先用ctx.request.accepts判断一下,客户端希望接受什么数据(根据 HTTP Request 的Accept字段),然后使用ctx.response.type指定返回类型。
const Koa = require('koa');
const app = new Koa();
app.use(function(ctx){
if(ctx.response.type = 'html'){
ctx.response.body = '<h1>Hello World</h1>';
}
});
app.listen(3000);
四、网页模板
const fs = require("fs");
const Koa = require('koa');
const app = new Koa();
app.use(function(ctx){
ctx.response.type = 'html';
ctx.response.body = fs.createReadStream('./template.html');
});
app.listen(3000);
五、原生路由
const fs = require('fs');
const Koa = require('koa');
const app = new Koa();
app.use(function(ctx){
if(ctx.request.path == '/template'){
ctx.response.type = 'html';
ctx.response.body = fs.createReadStream('./template.html');
}else{
ctx.response.body = '路径不正确!';
}
});
app.listen(3000);
六、原生路由用起来不太方便,我们可以使用封装好的koa-route
模块
安装模块:
npm install --save koa-route
改写原生路由配置:
const fs = require('fs');
const Koa = require('koa');
const route = require('koa-route');
const app = new Koa();
app.use(route.get('/template',function(ctx){
ctx.response.type = 'html';
ctx.response.body = fs.createReadStream('./template.html');
}));
app.listen(3000);
执行效果:
七、 静态资源
如果网站提供静态资源(图片、字体、样式表、脚本......),为它们一个个写路由就很麻烦,也没必要。koa-static
模块封装了这部分的请求。请看下面的例子
安装依赖:
npm install --save koa-static
从首页开始静态化文件路径:
const fs = require('fs');
const Koa = require('koa');
const route = require('koa-route');
const app = new Koa();
const path = require('path');
const serve = require('koa-static');
app.use(serve(path.join(__dirname)));
app.listen(3000);
单独制定某一个目录进行静态化:
app.use(serve(path.join(__dirname, './static')));
八、 重定向
有些场合,服务器需要重定向(redirect)访问请求。比如,用户登陆以后,将他重定向到登陆前的页面。ctx.response.redirect() 方法可以发出一个302跳转,将用户导向另一个路由。
九、错误处理
如果代码运行过程中发生错误,我们需要把错误信息返回给用户。HTTP 协定约定这时要返回500状态码。Koa 提供了ctx.throw()方法,用来抛出错误,ctx.throw(500)就是抛出500错误。
const fs = require('fs');
const Koa = require('koa');
const app = new Koa();
app.use((ctx,next)=>{
ctx.throw(500);
});
app.listen(3000);
如果将ctx.response.status设置成404,就相当于ctx.throw(404),返回404错误浏览器显示404页面"Page Not Found"。
十、error 事件的监听
运行过程中一旦出错,Koa 会触发一个error事件。监听这个事件,也可以处理错误。
Koa 框架 -- JavaScript 标准参考教程(alpha)
const Koa = require('koa');
const app = new Koa();
app.use((ctx,next)=>{
ctx.throw(500);
});
app.on('error', (err, ctx) => console.error('server error', err));
app.listen(3000);
访问 http://127.0.0.1:3000 ,你会在命令行窗口看到"server error xxx"。
需要注意的是,如果错误被 try...catch 捕获,就不会触发 error 事件。这时,必须调用ctx.app.emit('error', err, ctx);,手动释放 error 事件,才能让监听函数生效。
十一、cookie
const Koa = require('koa');
const app = new Koa();
app.use((ctx, next) => {
const n = Number(ctx.cookies.get('view') || 0) + 1;
ctx.cookies.set('view', n);
ctx.response.body = n + ' views';
});
app.listen(3000);
访问 http://127.0.0.1:3000 ,你会看到1 views。刷新一次页面,就变成了2 views。再刷新,每次都会计数增加1。
十二、表单
表单处理,表单就是 POST 方法发送到服务器的键值对。koa-body 模块可以用来从 POST 请求的数据体里面提取键值对。koa-body 模块还可以用来处理文件上传。
安装依赖:
npm install koa-body --save
表单代码:
const Koa = require('koa');
const app = new Koa();
const koaBody = require('koa-body');
app.use(koaBody());
app.use(function(ctx) {
const body = ctx.request.body;
console.log(ctx.request);//{ name: 'Hero' }
if (!body.name) ctx.throw(400, '什么也没有!');
ctx.body = {
name: body.name
};
});
app.listen(3000);
使用 curl 命令行工具进行测试。windows下使用curl命令&&常用curl命令 - 苍青浪 - 博客园
在 curl.exe 文件夹打开另一个命令行窗口,运行下面的命令。
输入:curl -X POST --data "name=hero" 127.0.0.1:3000
得到:{"name":"hero"}