路由:根据请求方式、请求地址的不同来执行对应的函数
安装
npm install koa-router --save
案例:
const Koa = require("koa");
const Router = require("koa-router");
let server = new Koa();
server.listen(8000);
let router = new Router();
router.get('/', async ctx=>{
ctx.body='aaa';
});
router.post('/upload', async ctx=>{
ctx.body='bbb';
});
router.get('/news', async ctx=>{
ctx.body='ccc';
})
server.use(router.routes()); // 中间件中使用router
get请求根目录’/’:
post请求/upload: 这里使用了form表单
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Page Title</title>
</head>
<body>
<form action="http://localhost:8000/upload" method="POST">
用户名: <input type="text" name="username">
<br>
<button>提交</button>
</form>
</body>
</html>
利用中间件处理路由的错误:
- 404 没有找到对应的资源
- 500 服务器错误
const Koa = require("koa");
const Router = require("koa-router");
let server = new Koa();
server.listen(8000);
let router = new Router();
server.use(async (ctx, next)=>{
try{
await next(); // 执行后代的代码
}catch(e){
// 如果后面的代码报错 返回500
ctx.body = "500"
}
})
router.get('/', async ctx=>{
ctx.body=user.name; // 故意写错,没有user.name
});
router.post('/upload', async ctx=>{
ctx.body='bbb';
});
router.get('/news', async ctx=>{
ctx.body='ccc';
})
server.use(router.routes()); // 中间件中使用router
server.use(async (ctx, next)=>{
try{
await next(); // 执行后代的代码
if(!ctx.body){ // 没有资源
ctx.body = "404"
}
}catch(e){
// 如果后面的代码报错 返回500
ctx.body = "500"
}
})
router.get('/news', async ctx=>{
// ctx.body='ccc'; // 没有内容
})
正式写法:
server.use(async (ctx, next)=>{
try{
await next(); // 执行后代的代码
if(!ctx.body){ // 没有资源
ctx.status = 404;
ctx.body = "not found"
}
}catch(e){
// 如果后面的代码报错 返回500
ctx.status = 500;
ctx.body = "server error"
}
})
给error页:
server.use(async (ctx, next)=>{
try{
await next(); // 执行后代的代码
if(!ctx.body){ // 没有资源
ctx.status = 404;
ctx.body = (await fs.readFile('./errors/404.html')).toString();
}
}catch(e){
// 如果后面的代码报错 返回500
ctx.status = 500;
ctx.body = (await fs.readFile('./errors/500.html')).toString();
}
})
读取文件后需要使用toString()方法,不然是二进制格式,会报错。
随便写就找不着这个路由,然后也找不到内容,就报404:
存在的问题:
反复读文件对性能有影响,我们可以把它前提读取,需要的时候使用。
(async () => {
// 写一个立即执行函数 先读文件
let data404 = await fs.readFile('./errors/404.html');
let error404 = data404.toString();
let data500 = await fs.readFile('./errors/500.html');
let error500 = data500.toString();
server.use(async (ctx, next)=>{
try{
await next(); // 执行后代的代码
if(!ctx.body){ // 没有资源
ctx.status = 404;
ctx.body = error404;
}
}catch(e){
// 如果后面的代码报错 返回500
ctx.status = 500;
ctx.body = error500;
}
})
router.get('/', async ctx=>{
ctx.body=user.name;
});
router.post('/upload', async ctx=>{
ctx.body='bbb';
});
router.get('/news', async ctx=>{
// ctx.body='ccc'; // 没有内容
})
server.use(router.routes());
})();
也可以用对象存储。