接着 Koa入门继续 传送门— Koa入门
我们监听的是3000端口 但是路径没有限制,所以输入以下路径都是OK的
http://localhost:3000/****
这样的话怎么处理 ?
按理说 我们想要每个路由对应不同的页面渲染
实现如下
// 导入koa,和koa 1.x不同,在koa2中,我们导入的是一个class,因此用大写的Koa表示:
const Koa = require('koa');
// 创建一个Koa对象表示web app本身:
const app = new Koa();
app.use(async (ctx, next) => {
const url = ctx.url;
ctx.response.type = 'text/html';
switch (url){
case '/':
ctx.response.body = 'Hello, koa2!
';
break;
case '/haha':
ctx.response.body = 'haha!
';
break;
case '/xixi':
ctx.response.body = 'xixi!
';
break;
}
await next(); // 调用下一个middleware
});
// 在端口3000监听:
app.listen(3000);
console.log('app started at port 3000...');
这样处理感觉会很笨重 所以我们还是需要做下集中处理的 当当当 koa-router 出现了
首先 安装依赖
npm install koa-router
package.json
{
"scripts": {
"start": "node app.js"
},
"dependencies": {
"koa": "^2.12.1",
"koa-router": "^9.0.1"
}
}
// 导入koa,和koa 1.x不同,在koa2中,我们导入的是一个class,因此用大写的Koa表示:
const Koa = require('koa');
// 创建一个Koa对象表示web app本身:
const app = new Koa();
// 注意require('koa-router')返回的是函数:
const route = require('koa-router');
const router = route()
app.use(async (ctx, next) => {
console.log(`Process ${
ctx.request.method} ${
ctx.request.url}...`);
await next();
});
// add url-route:
router.get('/', async (ctx, next) => {
ctx.response.body = 'Index
';
});
router.get('/:name', async (ctx, next) => {
var name = ctx.params.name;
ctx.response.body = `Hello,
${
name}!`;
});
// add router middleware:
app.use(router.routes());
// 在端口3000监听:
app.listen(3000);
console.log('app started at port 3000...');
这里 我们根据 get请求 可以在请求路径中使用带变量的/hello/:name 变量可以通过ctx.params.name访问
但是post 请求 是表单或者json的形式 它作为request的body发送,我们需要一个middleware来解析原始request请求,然后,把解析后的参数,绑定到ctx.request.body中 于是引入koa-bodyparser
// 导入koa,和koa 1.x不同,在koa2中,我们导入的是一个class,因此用大写的Koa表示:
const Koa = require('koa');
// 创建一个Koa对象表示web app本身:
const app = new Koa();
// 注意require('koa-router')返回的是函数:
const route = require('koa-router');
const router = route()
const bodyParser = require('koa-bodyparser');
const use_bodyParser = bodyParser();
router.get('/', async (ctx, next) => {
ctx.response.body = `Index
`;
});
router.post('/signin', async (ctx, next) => {
let name = ctx.request.body.name || '',
password = ctx.request.body.password || '';
console.log(`signin with name: ${
name}, password: ${
password}`);
if (name === 'admin' && password === '12345') {
ctx.response.body = `Welcome,
${
name}!`;
} else {
ctx.response.body = `Login failed!
`;
}
});
app.use(use_bodyParser); // 需要注册在koa-router之前
// add router middleware:
app.use(router.routes());
// 在端口3000监听:
app.listen(3000);
console.log('app started at port 3000...');
由于都写在app.js里面 代码冗余太多 所以我们优化下
新增containers文件夹 里面控制跳转路径以及其对应的逻辑处理
login.js
let fn_index = async (ctx, next) => {
ctx.response.body = `Index
`;
};
let fn_signin = async (ctx, next) => {
let name = ctx.request.body.name || '',
password = ctx.request.body.password || '';
console.log(`signin with name: ${
name}, password: ${
password}`);
if (name === 'koa' && password === '12345') {
ctx.response.body = `Welcome,
${
name}!`;
} else {
ctx.response.body = `Login failed!
`;
}
};
module.exports = {
'GET/': fn_index,
'POST/signin': fn_signin
};
hello.js
var fn_hello = async (ctx, next) => {
var name = ctx.params.name;
ctx.response.body = `Hello,
${
name}!`;
};
module.exports = {
'GET/hello/:name': fn_hello
};
app.js
// 导入koa,和koa 1.x不同,在koa2中,我们导入的是一个class,因此用大写的Koa表示:
const Koa = require('koa');
// 创建一个Koa对象表示web app本身:
const app = new Koa();
// 注意require('koa-router')返回的是函数:
const route = require('koa-router');
const router = route()
const bodyParser = require('koa-bodyparser');
const use_bodyParser = bodyParser();
const fs = require('fs')
function addControllers(router) {
// 先导入fs模块,然后用readdirSync列出文件
// 这里可以用sync是因为启动时只运行一次,不存在性能问题:
const files = fs.readdirSync(__dirname + '/controllers');
// 过滤出.js文件:
const js_files = files.filter((f) => {
return f.endsWith('.js');
});
for (let f of js_files){
// 可跳出循环
console.log('遍历对的controller为,', f);
const mapping = require(`${
__dirname}/controllers/${
f}`);
console.log('mapping', mapping)
findMapping(router,mapping)
}
}
function findMapping(router,mapping){
for (let url in mapping) {
// 遍历对象
console.log('拿到的url', url)
if (url.startsWith('GET')) {
const path = url.substring(3); // 取 跳转路径 / 或者 /hello/:name
console.log('那到的path', path);
router.get(path, mapping[url]);
} else if (url.startsWith('POST')) {
const path = url.substring(4); // 取 跳转路径/signin
router.post(path, mapping[url]);
}
}
}
// 调用方法
addControllers(router);
app.use(use_bodyParser); // 需要注册在koa-router之前
// add router middleware:
app.use(router.routes());
// 在端口3000监听:
app.listen(3000);
console.log('app started at port 3000...');
执行
npm run start
这样还是都写在了app.js里面
怎样才能抽出呢 只在app里面调用即可 这就涉及都了封装中间件,我理解 中间件就是一个封装的独立的逻辑的函数
所以在controllers文件夹下再设置一个contol.js 作为中间件 导出函数
control.js
const fs = require('fs')
function addControllers(router) {
// 先导入fs模块,然后用readdirSync列出文件
// 这里可以用sync是因为启动时只运行一次,不存在性能问题:
const files = fs.readdirSync(__dirname) ;
console.log("file", files)
// 过滤出.js文件:
const js_files = files.filter((f) => {
return f.endsWith('.js');
});
for (let f of js_files) {
// 可跳出循环
console.log('遍历对的controller为,', f);
const mapping = require(`${
__dirname}/${
f}`);
console.log('mapping', mapping)
findMapping(router, mapping)
}
}
function findMapping(router, mapping) {
for (let url in mapping) {
// 遍历对象
console.log('拿到的url', url)
if (url.startsWith('GET')) {
const path = url.substring(3); // 取 跳转路径 / 或者 /hello/:name
console.log('那到的path', path);
router.get(path, mapping[url]);
} else if (url.startsWith('POST')) {
const path = url.substring(4); // 取 跳转路径/signin
router.post(path, mapping[url]);
}
}
}
module.exports = function(){
console.log('haha')
const // 如果不传参数 ,默认为controllers目录
route = require('koa-router');// 注意require('koa-router')返回的是函数:
router = route();
// 调用方法
addControllers(router);
return router.routes(); // 必须return出去
}
app.js
// 导入controller middleware:
// 导入koa,和koa 1.x不同,在koa2中,我们导入的是一个class,因此用大写的Koa表示:
const Koa = require('koa');
// 创建一个Koa对象表示web app本身:
const app = new Koa();
const bodyParser = require('koa-bodyparser');
const use_bodyParser = bodyParser();
const controller = require('./controllers/control');
console.log(typeof controller)
app.use(use_bodyParser); // 需要注册在koa-router之前
// add router middleware:
app.use(controller()); // 调用return 出来的函数
// 在端口3000监听:
app.listen(3000);
console.log('app started at port 3000...');
启动
npm run start