(注,本文是慕课网学习笔记)
一,koa的介绍
通过本章的学习呢,大家基本上可以编写一个小型的web服务器。然后达到可以书写接口的能力。这样一来,我们就可以去配合一些后台语言,比如说java,如果说他们的接口返回的数据不符合我们前端的要求的话,可以在中间层我们用nodejs来写一个数据的处理,这样的话,当我们前端去请求这个中间层的时候,它就可以去后台(纯后台)读取数据,然后封装成我们前端所需要的数据,然后通过服务器端渲染的方式,推送到前端来,这样可以达到非常理想的性能要求。
二,koa的基本了解
三,初次尝试
npm init -y
npm install --save koa
const Koa =require('koa')
const app =new Koa()
app.use(async ctx =>{
ctx.body='hello world'
})
app.listen(3000)
新建js文件:
四,讲解koa
1,ctx到底是个啥?
我们可以把它打印出来
结果:
{
request: {
method: 'GET',
url: '/',
header: {
host: 'localhost:3000',
connection: 'keep-alive',
'cache-control': 'max-age=0',
'upgrade-insecure-requests': '1',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'sec-fetch-site': 'none',
'sec-fetch-mode': 'navigate',
'sec-fetch-user': '?1',
'sec-fetch-dest': 'document',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'zh-CN,zh;q=0.9'
}
},
response: {
status: 404,
message: 'Not Found',
header: [Object: null prototype] {}
},
app: { subdomainOffset: 2, proxy: false, env: 'development' },
originalUrl: '/',
req: '<original node req>',
res: '<original node res>',
socket: '<original node socket>'
}
可以看到ctx是一个对象,里面有这么几个属性:
2,使用koa-router中间件来处理处理URL映射
npm install -S koa-router
// 导入koa,和koa 1.x不同,在koa2中,我们导入的是一个class,因此用大写的Koa表示:
const Koa = require('koa');
//注意require('koa-router')返回的是函数:
const router = require('koa-router')();
//导入post请求参数处理的插件
const bodyParser = require('koa-bodyparser');
// 创建一个Koa对象表示web app本身:
const app = new Koa();
app.use(bodyParser());
//get请求的处理
router.get('/', async (ctx, next) => {
ctx.response.body = '这是首页的路由'; //响应体data中的信息
});
//get请求的处理
router.get('/testgetparams', async (ctx, next) => {
console.log(ctx.query); // { color: 'blue', size: 'small' } //我最常用的肯定是这个,也就是get请求参数放在:ctx.query之中
var text=ctx.query
ctx.response.body = text; //响应体data中的信息
});
//获取post请求的参数的方法
router.post('/testpostbody', async (ctx, next) => {
var text=ctx.request.body //我最常用的肯定是这个,也就是get请求参数放在:ctx.request.body之中
ctx.response.body = text; //响应体data中的信息
});
app.use(router.routes()); //把这之前定义的所有router利用app.use作为中间件去处理,
app.use(router.allowedMethods()); //它是一个拦截器,拦截所有的请求,如果这个请求此服务器没有定义,就返回4xx或者5xx的错误
// 在端口3000监听:
app.listen(3000);
console.log('服务器创建储成功,启动的端口是3000');
也就是说通过koa-router实现了不同的url地址,服务端做出不同的响应,并可以接收请求参数,还可以将服务端处理后的数据放在ctx.response.body中,从而给前端。
3,koa的工作原理:洋葱模型,先进后出
具体代码:
// 导入koa,和koa 1.x不同,在koa2中,我们导入的是一个class,因此用大写的Koa表示:
const Koa = require('koa');
//注意require('koa-router')返回的是函数:
const router = require('koa-router')();
//导入post请求参数处理的插件
const bodyParser = require('koa-bodyparser');
// 创建一个Koa对象表示web app本身:
const app = new Koa();
app.use(bodyParser());
const middle1= function async(ctx,next){
console.log("第一个中间件执行了")
next()
console.log("第一个中间件执行结束")
}
const middle2= function async(ctx,next){
console.log("第二个中间件执行了")
next()
console.log("第二个中间件执行结束")
}
const middle3= function async(ctx,next){
console.log("第三个中间件执行了")
// next()
console.log("第二个中间件执行结束")
}
app.use(middle1)
app.use(middle2)
app.use(middle3)
app.use(router.routes()) //把这之前定义的所有router利用app.use作为中间件去处理,
.use(router.allowedMethods()); //它是一个拦截器,拦截所有的请求,如果这个请求此服务器没有定义,就返回4xx或者5xx的错误
// 在端口4000监听:
app.listen(4000);
console.log('服务器创建储成功,启动的端口是4000');
4,koa里面使用async和await,可以使用同步的方式书写异步操作代码
const router = require('koa-router')();
// 创建一个Koa对象表示web app本身:
const app = new Koa();
router.get('/async',async (ctx)=>{
let result =await new Promise((resolve)=>{
setTimeout(function(){
resolve("hello world 2s later!")
},2000)
})
ctx.response.body=result
})
app.use(router.routes())
.use(router.allowedMethods());
// 在端口3000监听:
app.listen(3000);
console.log('服务器创建储成功,启动的端口是3000');
这段代码可以模拟后台服务器进行了2s的数据处理操作,然后才返回数据
五,使用koa开发RESETful接口
1, 第一个中间件是koa-router
2,第二个是koa-body
他的作用是转译json格式的数据
3,第三个是@koa/cors跨域处理的
npm install -S koa-body @koa/cors koa-router
4,第一个小例子:
const Koa = require('koa');
//注意require('koa-router')返回的是函数:
const router = require('koa-router')();
const cors=require('@koa/cors')
const koaBody =require('koa-body')
// 创建一个Koa对象表示web app本身:
const app = new Koa();
//定义路由接口
router.post('/post',async (ctx)=>{
let {body} =ctx.request //es6写法,把ctx中的request赋值给body
console.log(body)
console.log(ctx.request)
ctx.response.body={
...body
}
})
//app.use()执行中间件,又因为中间件的执行依据洋葱模型,是有执行顺序的。所以这里先执行这个:
app.use(koaBody())
app.use(cors())
app.use(router.routes()) //把这之前定义的所有router利用app.use作为中间件去处理,
.use(router.allowedMethods()); //它是一个拦截器,拦截所有的请求,如果这个请求此服务器没有定义,就返回4xx或者5xx的错误
// 在端口3000监听:
app.listen(3000);
console.log('服务器创建储成功,启动的端口是3000');
5,router.prefix(’/path’)
他的作用是给所有的请求都加上一个路径,也就是前端的url要加这个才可以请求到:
const Koa = require('koa');
//注意require('koa-router')返回的是函数:
const router = require('koa-router')();
const cors=require('@koa/cors')
const koaBody =require('koa-body')
// 创建一个Koa对象表示web app本身:
const app = new Koa();
router.prefix('/api')
//定义路由接口
router.post('/post',async (ctx)=>{
let {body} =ctx.request //es6写法,把ctx中的request赋值给body
console.log(body)
console.log(ctx.request)
ctx.response.body={
...body
}
})
//app.use()执行中间件,又因为中间件的执行依据洋葱模型,是有执行顺序的。所以这里先执行这个:
app.use(koaBody())
app.use(cors())
app.use(router.routes()) //把这之前定义的所有router利用app.use作为中间件去处理,
.use(router.allowedMethods()); //它是一个拦截器,拦截所有的请求,如果这个请求此服务器没有定义,就返回4xx或者5xx的错误
// 在端口3000监听:
app.listen(3000);
console.log('服务器创建储成功,启动的端口是3000');
这时候postman就得加上api才可以访问到了;
6,获取get请求的参数params
//get请求的处理
router.get('/testgetparams', async (ctx, next) => {
console.log(ctx.query); // { color: 'blue', size: 'small' } //我最常用的肯定是这个,也就是get请求参数放在:ctx.query之中
var text=ctx.query
ctx.response.body = text; //响应体data中的信息
});
但是它返回的是这样的json,我们想要的是对象:
7,koa-json中间件
const Koa = require('koa');
//注意require('koa-router')返回的是函数:
const router = require('koa-router')();
const cors=require('@koa/cors')
const koaBody =require('koa-body')
const json=require('koa-json')
// 创建一个Koa对象表示web app本身:
const app = new Koa();
router.prefix('/api')
//定义路由接口
router.post('/post',async (ctx)=>{
let {body} =ctx.request //es6写法,把ctx中的request赋值给body
console.log(body)
console.log(ctx.request)
ctx.response.body={
...body
}
})
//get请求的处理
router.get('/testgetparams', async (ctx, next) => {
console.log(ctx.query); // { color: 'blue', size: 'small' } //我最常用的肯定是这个,也就是get请求参数放在:ctx.query之中
var text=ctx.query
ctx.response.body = text; //响应体data中的信息
});
//app.use()执行中间件,又因为中间件的执行依据洋葱模型,是有执行顺序的。所以这里先执行这个:
app.use(koaBody())
app.use(cors())
app.use(json({pretty:false,param:'pretty'}))
app.use(router.routes()) //把这之前定义的所有router利用app.use作为中间件去处理,
.use(router.allowedMethods()); //它是一个拦截器,拦截所有的请求,如果这个请求此服务器没有定义,就返回4xx或者5xx的错误
// 在端口3000监听:
app.listen(3000);
console.log('服务器创建储成功,启动的端口是3000');