一、安装
- 生成配置文件:cnpm init --yes
- koa框架:cnpm install --save-dev koa或者cnpm install --save-dev koa@2.0.0
二、koa入门
const koa=require("koa");
const app=new koa();
let port=8080;
let host='localhost';
app.use(async (ctx,next)=>{
console.log("http请求");
await next();
ctx.response.type="text/html";
ctx.response.body="<h3>koa框架</h3>";
});
app.listen(port,host,()=>{
console.log(`http://${host}:${port}`);
})
- 其中,参数ctx是由koa传入的封装了request和response的变量,我们可以通过它访问request和response,next是koa传入的将要处理的下一个异步函数。
- 上面的异步函数中,我们首先用await next();处理下一个异步函数,然后,设置response的Content-Type和内容。
- 由async标记的函数称为异步函数,在异步函数中,可以用await调用另一个异步函数,这两个关键字将在ES7中引入。
- 让我们再仔细看看koa的执行逻辑。核心代码是:
app.use(async (ctx, next) => {
await next();
ctx.response.type = 'text/html';
ctx.response.body = '<h1>Hello, koa2!</h1>';
});
- 每收到一个http请求,koa就会调用通过app.use()注册的async函数,并传入ctx和next参数。
- 我们可以对ctx操作,并设置返回内容。但是为什么要调用await next()?
原因是koa把很多async函数组成一个处理链,每个async函数都可以做一些自己的事情,然后用await next()来调用下一个async函数。我们把每个async函数称为middleware,这些middleware可以组合起来,完成很多有用的功能。 - middleware的顺序很重要,也就是调用app.use()的顺序决定了middleware的顺序。
- 此外,如果一个middleware没有调用await next()会怎么办?答案是后续的middleware将不再执行了。
- 最后注意ctx对象有一些简写的方法,例如ctx.url相当于ctx.request.url,ctx.type相当于ctx.response.type。
三、处理URL
- 在hello-koa工程中,我们处理http请求一律返回相同的HTML,这样虽然非常简单,但是用浏览器一测,随便输入任何URL都会返回相同的网页。
1.处理URL基本方法
app.use(async ctx=>{
let url=ctx.request.url;
console.log(url);
if(url=="/"){
ctx.response.body="首页";
}
else if(url=="/login"){
ctx.response.body="登录";
}
});
app.use(async (ctx,next)=>{
if(ctx.request.path=="/"){
ctx.response.body="首页";
}
else{
await next();
}
});
app.use(async (ctx,next)=>{
if(ctx.request.path=="/login"){
ctx.response.body="登录";
}
else{
await next();
}
});
app.use(async (ctx,next)=>{
if(ctx.request.path=="/regest"){
ctx.response.body="注册";
}
else{
await next();
}
});
- 这么写是可以运行的,但是好像有点繁琐。
- 应该有一个能集中处理URL的middleware,它根据不同的URL调用不同的处理函数,这样,我们才能专心为每个URL编写处理函数。
2.使用路由koa-router处理URL
- 为了处理URL,我们需要引入koa-router这个middleware,让它负责处理URL映射。
- 安装koa-router:cnpm install --save-dev koa-router
const koa=require("koa");
const app=new koa();
const router=require("koa-router")();
const bodyparser=require("koa-bodyparser");
app.use(bodyparser());
let port=8080;
let host='localhost';
app.use(async (ctx,next)=>{
console.log(ctx.request.url);
await next();
})
router.get('/',async (ctx,next)=>{
ctx.response.body="首页";
});
router.get('/login',async (ctx,next)=>{
ctx.response.body="登录";
});
router.get("/user",async (ctx,next)=>{
console.log(ctx.request.query);
ctx.response.body="获取get传值";
})
router.get("/regest",async (ctx,next)=>{
ctx.response.body=`
<form action='/regest' method='post'>
<input type='text' name='id'/>
<button>注册</button>
</form>
`
});
router.post('/regest',async (ctx,next)=>{
console.log(ctx.request.body);
ctx.response.body="注册成功";
});
app.use(router.routes());
app.listen(port,host,()=>{
console.log(`http://${host}:${port}`);
});
3.路由的模块化封装
const koa=require("koa");
const app=new koa();
const bodyparser=require("koa-bodyparser");
app.use(bodyparser());
let port=8080;
let host='localhost';
let router=require("./router/routerMiddle");
app.use(router());
app.listen(port,host,()=>{
console.log(`http://${host}:${port}`);
});
let index = require("./routes/index");
let login=require("./routes/login");
let addController=(router,route)=>{
for(let url in route){
if(url.startsWith("GET ")){
let path=url.substring(4);
router.get(path,route[url]);
}
else if(url.startsWith("POST ")){
let path=url.substring(5);
router.post(path,route[url]);
}
else{
console.log("404");
}
}
}
module.exports=()=>{
let routes=Object.assign({},index,login),
router=require("koa-router")();
addController(router,routes);
return router.routes();
}
let f_index=async (ctx,next)=>{
ctx.response.body="首页";
}
let f_regest=async (ctx,next)=>{
ctx.response.body="表单注册";
}
module.exports={
'GET /':f_index,
'POST /':f_regest
}
let login_index=async (ctx,next)=>{
ctx.response.body="登录界面";
}
let login_dologin=async (ctx,next)=>{
ctx.response.body="登录成功";
}
module.exports={
'GET /login':login_index,
'POST /dologin':login_dologin
}