* Hello Koa2 *

app.js文件:

// 第一步 引入koa包
const Koa = require('koa');

// 第二步 创建koa实例
const app = new Koa();

// 第三步 使用中间件
app.use(async (ctx,next) => {
await next();

ctx.response.type = 'text/html';
ctx.response.body = '<h1>Hello Koa2!</h1>';

});

app.listen(3000);

console.log('Server is running at port 3000...');

Koa 中间件 middleware

每收到一个http请求,koa就会调用通过app.use()注册的async函数,并传入ctx和next参数。我们可以对ctx操作,并设置返回内容。但是为什么要调用await next()?原因是koa把很多async函数组成一个处理链,每个async函数都可以做一些自己的事情,然后用await next()来调用下一个async函数。我们把每个async函数称为middleware,这些middleware可以组合起来,完成很多有用的功能。
// 第一步 引入koa包
const Koa = require('koa');

// 第二步 创建koa实例
const app = new Koa();

// 第三步 使用中间件

// 获取用户请求的方式和请求的根目录的路径
app.use(async (ctx,next) => {
console.log(`${ctx.request.method} ${ctx.request.url}`); //GET /index
await next(); //调用下一个中间件
});

// 打印用户请求后台服务到返回数据的时间
app.use(async (ctx,next) => {

const startTime = new Date().getTime();//当前的时间戳

await next(); //先调用后面的中间件

const endTime = new Date().getTime(); //输出完的时间戳

console.log((endTime - startTime) + 'ms');

});

app.use(async (ctx,next) => {
await next();

ctx.response.type = 'text/html';
ctx.response.body = '<h1>Hello Koa2!</h1>';

});

app.listen(3000);

console.log('Server is running at port 3000...');
如果一个middleware没有调用await next(),会怎么办?答案是后续的middleware将不再执行了。理解了middleware,我们就已经会用koa了!

最后注意ctx对象有一些简写的方法,例如ctx.url相当于ctx.request.url,ctx.type相当于ctx.response.type。

处理 URL

正常情况下,我们应该对不同的URL调用不同的处理函数,这样才能返回不同的结果。
// 第一步 引入koa包
const Koa = require('koa');

// 第二步 创建koa实例
const app = new Koa();

// 第三步 使用中间件处理URL
app.use(async (ctx,next) => {

if(ctx.request.path === '/'){
ctx.response.type = 'text/html';
ctx.response.body = '<h1>这是首页~</h1>';
}else{
await next();
}

});

app.use(async (ctx,next) => {

if(ctx.request.path === '/detail'){
ctx.response.type = 'text/html';
ctx.response.body = '<h1>这是详情页~</h1>';
}else{
await next();
}

});


app.use( async (ctx,next) => {
ctx.response.type = 'text/html';
ctx.response.body = '404,没有相关的信息';
});


app.listen(3000);

console.log('Server is running at port 3000...');
这么写是可以运行的,但是好像有点蠢。
应该有一个能集中处理URL的middleware,它根据不同的URL调用不同的处理函数,这样,我们才能专心为每个URL编写处理函数。

koa-router

router 处理get请求:

// 第一步 引入koa包
const Koa = require('koa');

//第二步 引入koa-router包
const router = require('koa-router')();

// 第三步 创建koa实例
const app = new Koa();

app.use( async (ctx,next) => {
console.log(`${ctx.method} ${ctx.url}`);
await next();
});

// koa-router GET请求
router.get('/', async (ctx, next) => {
ctx.response.body = '<h1>这是首页</h1>';
});

router.get('/index', async (ctx, next) => {
ctx.response.body = '<h1>这是首页</h1>';
});

router.get('/detail/:id', async (ctx, next) => {
var id = ctx.params.id;
ctx.response.body =`/h1>`;
});

// app使用router 中间件
app.use(router.routes());

app.listen(3000);

console.log('Server is running at port 3000...');

router处理post请求:

用post请求处理URL时,我们会遇到一个问题:post请求通常会发送一个表单,或者JSON,它作为request的body发送,但无论是Node.js提供的原始request对象,还是koa提供的request对象,都不提供解析request的body的功能!

所以,我们又需要引入另一个middleware来解析原始request请求,然后,把解析后的参数,绑定到ctx.request.body中。

koa-bodyparser就是用来干这个活的。
// 第一步 引入koa包
const Koa = require('koa');

//第二步 引入koa-router包
const router = require('koa-router')();

// 第三步 解析post body的引包
const bodyParser = require('koa-bodyparser');

// 第三步 创建koa实例
const app = new Koa();

app.use( async (ctx,next) => {
console.log(`${ctx.method} ${ctx.url}`);
await next();
});

// koa-router GET请求
router.get('/', async (ctx, next) => {
ctx.response.body = '<h1>这是首页</h1>';
});

router.get('/index', async (ctx, next) => {
ctx.response.body = '<h1>这是首页</h1>';
});

router.get('/login', async (ctx, next) => {
ctx.response.body = `<h1>这是注册页</h1>
<form method='post' action='/signin'>
<div style='margin:10px 0'>用户名:<input type='text' placeholder='请输入你要注册的名字' name='username'></div>
<div>密 码:<input type='password' placeholder='请输入你要注册的密码' name='password'></div>
<div style='margin:10px 0'><input type='submit' value='提 交'></div>
</form>`;
});

router.post('/signin',async (ctx,next) => {
var username = ctx.request.body.username || '';
var password = ctx.request.body.password || '';

console.log(username + '//' + password);

if(username == 'qiepl' && password == 'adley1234'){
ctx.response.body = `欢迎${username}登陆!`;
}else{
ctx.response.body = '登陆失败!';
}

});

router.get('/detail/:id', async (ctx, next) => {
var id = ctx.params.id;
ctx.response.body =`/h1>`;
});

// app使用bodyParser 中间件
app.use(bodyParser());

// app使用router 中间件
app.use(router.routes());

app.listen(3000);

console.log('Server is running at port 3000...');