前言
由于业务需求,故大致学习一下KOA框架。
环境搭建
mkdir KOA
cd KOA
npm init -y # 初始化package.json文件
npm install --save koa # 安装KOA
HelloKoa
const Koa = require('koa')
const app = new Koa()
app.use(async (ctx) => {
ctx.body = 'hello koa'
})
app.listen(3000)
console.log('listening at port 3000')
GET请求的接收
原生方法
const Koa = require('koa');
const app = new Koa();
app.use(async (ctx) => {
let url = ctx.url;
// 从request中获取GET请求
let request = ctx.request;
let req_query = request.query;// query:返回的是格式化好的参数对象
let req_querystring = request.querystring;// 返回的是请求字符串
// 从上下文中直接获取
let ctx_query = ctx.query;
let ctx_querystring = ctx.querystring;
ctx.body = {
url,
req_query,
req_querystring,
ctx_query,
ctx_querystring
}
});
app.listen(3000, () => {
console.log('listening at port 3000');
});
POST接收请求
Caps 1
获取POST请求步骤:
- 解析上下文ctx中的原生nodex.js对象req。
- 将POST表单数据解析成query string-字符串.(例如:user=jspang&age=18)
- 将字符串转换成JSON格式。
ctx.request和ctx.req的区别
- ctx.request:是Koa2中context经过封装的请求对象,它用起来更直观和简单。
- ctx.req:是context提供的node.js原生HTTP请求对象。这个虽然不那么直观,但是可以得到更多的内容,适合我们深度编程。
ctx.method 得到请求类型,用法如下
const Koa = require('koa');
const app = new Koa();
app.use(async(ctx)=>{
// 当请求时GET请求时,显示表单让用户填写
if(ctx.url==='/' && ctx.method === 'GET'){
let html =`
<h1>Koa request post demo</h1>
<form method="POST" action="/">
<p>userName</p>
<input name="userName" /> <br/>
<p>age</p>
<input name="age" /> <br/>
</form>
`;
ctx.body =html;
// 当请求时POST请求时
}else if(ctx.url==='/' && ctx.method === 'POST'){
ctx.body='接收到请求';
}else{
// 其它请求显示404页面
ctx.body='<h1>404!</h1>';
}
})
app.listen(3000,()=>{
console.log('listening at port 3000');
})
Caps 2
声明一个方法,使用Promise对象解析。
function parsePostData(ctx) {
return new Promise((resolve, reject) => {
try {
let postdata = "";
ctx.req.on('data', (data) => {
postdata += data
})
ctx.req.addListener("end", function () {
resolve(postdata);
})
} catch (error) {
reject(error);
}
});
}
完整代码
const Koa = require('koa')
const app = new Koa()
function parsePostData(ctx) {
return new Promise((resolve, reject) => {
try {
let postdata = "";
ctx.req.on('data', (data) => {
postdata += data
})
ctx.req.addListener("end", function () {
resolve(postdata);
})
} catch (error) {
reject(error);
}
});
}
function parseQueryStr(queryStr) {
if (queryStr == '' || queryStr == null) {
return {}
}
let queryData = {};
let queryStrList = queryStr.split('&');
console.log(queryStrList);
for (let [index, queryStr] of queryStrList.entries()) {
let itemList = queryStr.split('=');
// console.log(itemList);
queryData[itemList[0]] = decodeURIComponent(itemList[1]);
}
return queryData
}
app.use(
async (ctx) => {
let url = ctx.url;
let request = ctx.request;
let req_query = request.query;
let req_querystring = request.querystring;
//从上下文中直接获取
let ctx_query = ctx.query;
let ctx_querystring = ctx.querystring;
// POST
let postData = await parsePostData(ctx)
postData = parseQueryStr(postData)
ctx.body = {
url,
req_query,
req_querystring,
ctx_query,
ctx_querystring,
postData
}
}
)
app.listen(3000, () => {
console.log('listening at port 3000')
})
koa-bodyparser中间件
上面的写法是原生实现的,koa已经给我们造好了一个轮子,也就是koa-bodyparser。对于POST请求的处理,koa-bodyparser中间件可以把koa上下文的formData数据解析到ctx.request.body中。
安装
npm install --save koa-bodyparser@3
完整代码
const Koa = require('koa');
const app = new Koa();
const bodyParser = require('koa-bodyparser');
app.use(bodyParser());
app.use(async (ctx) => {
if (ctx.url === '/' && ctx.method === 'GET') {
//显示表单页面
let html = `
<h1>JSPang Koa2 request POST</h1>
<form method="POST" action="/">
<p>userName</p>
<input name="userName" /><br/>
<p>age</p>
<input name="age" /><br/>
</form>
`;
ctx.body = html;
} else if (ctx.url === '/' && ctx.method === 'POST') {
let postData = ctx.request.body;
ctx.body = postData;
} else {
ctx.body = '<h1>404!</h1>';
}
});
app.listen(3000, () => {
console.log('listening at port 3000');
});
Koa原生路由实现
const Koa = require('koa');
const fs = require('fs');// nodejs的fs模块
const app = new Koa();
function render(page) {
return new Promise((resolve, reject) => {
let pageUrl = `./page/${page}`;
fs.readFile(pageUrl, "binary", (err, data) => {
if (err) {
reject(err)
} else {
resolve(data);
}
})
})
}
async function route(url) {
let page = '404.html';
switch (url) {
case '/':
page = 'index.html';
break;
case '/index':
page = 'index.html';
break;
case '/404':
page = '404.html';
break;
default:
break;
}
let html = await render(page);
return html;
}
app.use(async (ctx) => {
let url = ctx.request.url;
let html = await route(url);
ctx.body = html;
})
app.listen(3000);
console.log('listening at 3000');
Koa-router中间件
安装
npm install --save koa-router
const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
// 多页面的添加只要继续在下面填写get或者Post即可
router.get('/', function (ctx, next) {
ctx.body = "Hello Koa";
})
.get('/todo', (ctx, next) => {
ctx.body = "Todo page"
});
app
.use(router.routes())
.use(router.allowedMethods());
app.listen(3000, () => {
console.log('listening at port 3000');
});
Koa中使用cookies
了解基本的参数
- ctx.cookies.get(name,[optins]):读取上下文请求中的cookie。
- ctx.cookies.set(name,value,[options]):在上下文中写入cookie。
写入cookie操作
const Koa = require('koa');
const app = new Koa();
app.use(async (ctx) => {
if (ctx.url === '/index') {
ctx.cookies.set(
'MyName', 'Carlos'
);
ctx.body = 'cookie is ok';
} else {
ctx.body = 'hello world'
}
});
app.listen(3000, () => {
console.log('listening at port 3000');
})
Cookie参数配置
- domain:写入cookie所在的域名
- path:写入cookie所在的路径
- maxAge:Cookie最大有效时长
- expires:cookie失效时间
- httpOnly:是否只用http请求中获得
- overwirte:是否允许重写
const Koa = require('koa');
const app = new Koa();
app.use(async (ctx) => {
if (ctx.url === '/index') {
ctx.cookies.set(
'MyName', 'Carlos', {
domain: '127.0.0.1', // 写cookie所在的域名
path: '/index', // 写cookie所在的路径
maxAge: 1000 * 60 * 60 * 24, // cookie有效时长
expires: new Date('2020-3-12'), // cookie失效时间
httpOnly: false, // 是否只用于http请求中获取
overwrite: false // 是否允许重写
}
);
ctx.body = 'cookie is ok';
} else {
ctx.body = 'hello world'
}
});
app.listen(3000, () => {
console.log('listening at port 3000');
})
读取Cookie
const Koa = require('koa');
const app = new Koa();
app.use(async (ctx) => {
if (ctx.url === '/index') {
ctx.cookies.set(
'MyName', 'Carlos', {
domain: '127.0.0.1', // 写cookie所在的域名
path: '/index', // 写cookie所在的路径
maxAge: 1000 * 60 * 60 * 24, // cookie有效时长
expires: new Date('2020-3-12'), // cookie失效时间
httpOnly: false, // 是否只用于http请求中获取
overwrite: false // 是否允许重写
}
);
ctx.body = 'cookie is ok';
} else {
if (ctx.cookies.get('MyName')) {
ctx.body = ctx.cookies.get('MyName');
} else {
ctx.body = 'Cookie is none';
}
}
});
app.listen(3000, () => {
console.log('listening at port 3000');
})