简介
Koa 是现在最流行的基于Node.js平台的web开发框架。
- koa 是由 Express 原班人马打造的
- 致力于成为一个更小、更富有表现力、更健壮的 Web 框架。
- koa 不在内核方法中绑定任何中间件,它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。
官网:koajs.com/
中文社区:www.koajs.com.cn/
安装
npm i koa
hello world
- Koa 应用程序是一个包含
一组中间件函数的对象
,它是按照类似堆栈的方式组织和执行的。
const Koa = require('koa');
const app = new Koa();
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
级联中间件
app.use(fn1);
app.use(fn2);
app.use(fn3);
const Koa = require('koa');
const app = new Koa();
// x-response-time
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
ctx.set('X-Response-Time', `${ms}ms`);
});
// logger
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}`);
});
// response
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);
上下文(Context)
-
Koa Context 将 node 的 request 和 response 对象封装到单个对象中,为编写 Web 应用程序和 API 提供了许多有用的方法
-
ctx.request // 这是 koa Request
-
ctx.response // 这是 koa Response
-
ctrx.req //原始的http请求对象
-
ctx.res //原始的http响应对象
-
ctx.app 应用程序实例引用
-
ctx.request是Koa2中context经过封装的请求对象
-
绕过 Koa 的 response 处理是 不被支持的
获取请求参数
const Koa = require('koa');
const app = new Koa();
app.use(async (ctx) => {
console.log(ctx.method); //获取请求方法
console.log(ctx.url); //获取请求URL
console.log(ctx.query); //获取解析的查询字符串对象
console.log(ctx.querystring); //根据 ? 获取原始查询字符串
console.log(ctx.headers);//获取请求头对象
ctx.body = ctx.url;
});
app.listen(3000, () => {
console.log('server is starting at port 3000');
});
获取请求体
const querystring = require('querystring');
const app = new Koa();
app.use(async (ctx) => {
if (ctx.method == 'GET') {
ctx.set('Content-Type', 'text/html;charset=utf-8');
ctx.body = (
`
<form method="POST">
<input name="username" >
<input type="submit">
</form>
`
);
} else if (ctx.method == 'POST') {
ctx.set('Content-Type', 'application/json');
ctx.body = await parsePostBody(ctx);
} else {
ctx.body = 'Not Allowed';
}
});
/**
* 自己封装函数处理post提交的数据
*/
function parsePostBody(ctx) {
return new Promise(function (resolve, reject) {
let buffers = [];
ctx.req.on('data', function (data) {
buffers.push(data);
});
ctx.req.on('end', function (data) {
let body = buffers.toString();
body = querystring.parse(body);
resolve(body);
});
ctx.req.on('error', function (errdata) {
reject(err);
});
});
}
app.listen(3000, () => {
console.log('server is starting at port 3000');
});
使用中间件获取普通请求体
npm i koa-bodyparser -S
const Koa = require('koa');
const querystring = require('querystring');
const bodyParser = require('koa-bodyparser');
const app = new Koa();
app.use(bodyParser());
app.use(async (ctx) => {
if (ctx.method == 'GET') {
ctx.set('Content-Type', 'text/html;charset=utf-8');
ctx.body = (
`
<form method="POST">
<input name="username" >
<input type="submit">
</form>
`
);
} else if (ctx.method == 'POST') {
ctx.set('Content-Type', 'application/json');
ctx.body = ctx.request.body;
} else {
ctx.body = 'Method Not Allowed';
}
});
app.listen(3000, () => {
console.log('server is starting at port 3000');
});
获取包含文件的请求体
npm i koa-better-body
const Koa = require('koa');
const querystring = require('querystring');
const path = require('path');
const convert = require('koa-convert');
const bodyParser = require('koa-better-body');
const app = new Koa();
app.use(convert(bodyParser({
uploadDir: path.join(__dirname, 'uploads'),
keepExtensions: true
})));
app.use(async (ctx) => {
if (ctx.method == 'GET') {
ctx.set('Content-Type', 'text/html;charset=utf-8');
ctx.body = (
`
<form method="POST" enctype="multipart/form-data">
<input name="username" >
<input name="avatar" type="file" >
<input type="submit">
</form>
`
);
} else if (ctx.method == 'POST') {
ctx.set('Content-Type', 'application/json');
console.log(ctx.request.fields);
ctx.body = ctx.request.body;
} else {
ctx.body = 'Method Not Allowed';
}
});
app.listen(3000, () => {
console.log('server is starting at port 3000');
});
路由中间件
npm i koa-router
单路由
const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa();
let user = new Router();
user.get('/user', function (ctx) {
ctx.body = 'get user ';
}).get('/query/:id', function (ctx) {
ctx.body = ctx.params;
}).post('/user', function (ctx) {
ctx.body = 'post user ';
}).get('/home', function (ctx) {
ctx.body = 'get home ';
});
app.use(user.routes());
app.listen(3000, () => {
console.log('server is starting at port 3000');
});
多级路由
let user = new Router();
user.get('/add', function (ctx) {
ctx.body = 'get user add ';
});
let article = new Router();
article.get('/add', function (ctx) {
ctx.body = 'get article add ';
});
let router = new Router();
router.use('/user', user.routes());
router.use('/article', article.routes());
app.use(router.routes());
会话-cookie
- ctx.cookies.get(name,[optins]):读取上下文请求中的cookie。
- ctx.cookies.set(name,value,[options]):在上下文中写入cookie。
- domain:写入cookie所在的域名
- path:写入cookie所在的路径
- maxAge:Cookie最大有效时长
- expires:cookie失效时间
- httpOnly:是否只用http请求中获得
- overwirte:是否允许重写
app.use(async (ctx, next) => {
if (ctx.url == '/write') {
ctx.cookies.set('name', 'gogery');
ctx.body = 'write cookie';
} else {
next();
}
});
app.use(async (ctx) => {
if (ctx.url == '/read') {
ctx.body = ctx.cookies.get('name');
}
});
会话-session
npm install koa-session
const Koa = require('koa');
const session = require('koa-session');
const app = new Koa();
app.keys = ['some secret string'];
app.use(session({}, app));
app.use(async (ctx) => {
let visit = ctx.session.visit;
if (visit) {
visit = visit + 1;
} else {
visit = 1;
}
ctx.session.visit = visit;
ctx.body = `这是你的第${visit}次访问`;
});
app.listen(3000);
模板引擎
npm i koa-views ejs
const Koa = require('koa');
const views = require('koa-views');
const path = require('path');
const app = new Koa();
app.use(views(path.join(__dirname, './views'), {
extension: 'ejs'
}));
app.use(async ctx => {
await ctx.render('index', { title: '模板引擎' });
});
app.listen(3000, () => {
console.log('server is starting at port 3000');
静态资源中间件
npm i koa-static
const static = require('koa-static')
const app = new Koa()
app.use(static(path.join( __dirname, 'public')))
app.use( async ( ctx ) => {
ctx.body = 'File Not Found'
})