Промежуточное ПО, обычно используемое в Koa:
- koa-session: позволить HTTP без сохранения состояния иметь состояние, а сеанс, основанный на cookie, для сохранения информации в фоновом режиме.
- koa-mysql: инкапсулирует операторы SQL, которые необходимо использовать.
- koa-mysql-session: когда вы не хотите, чтобы сеанс хранился в памяти, и когда вы хотите сохранить сеанс, используйте базу данных mysql
- koa-router: фон будет получать URL-адреса различных запросов, а маршрутизация будет использовать различную логику обработки в соответствии с разными URL-адресами.
- koa-view: при запросе html-страницы фон будет использовать механизм шаблонов для рендеринга данных в шаблон, а затем вернуть их в фон
- koa-static: При запросе img, js, css и других файлов никакой другой логики не требуется, нужно только прочитать файл
- koa-better-body: когда сообщение загружает файл, анализировать тело запроса
Серия статей КОА:
- koa framework будет написан - (koa basic framework)
- Фреймворк KOA тоже будет писать - (KOA-ROUTER)
- Будет использоваться и написана структура koa — (koa-view, koa-static)
- Будет использоваться и написана структура koa — (koa-bodyparser, koa-better-body)
Статические и динамические ресурсы
В сетевых запросах запросы часто делятся на два типа, один — это статические ресурсы, которые считываются непосредственно из файлового хранилища сервера, а другой — это динамические ресурсы, которые, как правило, сначала должны получить данные из базы данных, а затем пройти через определенные обработка и, наконец, возврат клиенту.
- koa-static: используется для обработки доступа к статическим ресурсам, поскольку не задействует другие процессы обработки, а просто читает файлы, поэтому извлекается отдельно.
- KOA-View используется для использования данных и шаблонов для рендеринга HTML-страницы, логика шаблона рендеринга такая же, поэтому он также отделен отдельно.
koa-static
- Определить, существует ли запрошенный файл, если он существует, прочитать файл и вернуться
- Если запрошенный файл не существует, по умолчанию возвращается index.html текущего файла.
В соответствии с приведенной выше идеей, чтобы получить простую версию static, вы можете сохранить static в файле js отдельно, а затем потребовать его, что аналогично koa:
const Koa = require('koa');
const path = require('path');
const Router = require('koa-router');
const fs = require('fs');
const {promisify} = require('util'); //将函数promise化
const stat = promisify(fs.stat); //用来获取文件的信息
const mime = require('mime'); //mime类型获取插件
let app = new Koa();
let router = new Router();
function static(dir) {
return async (ctx,next)=>{
let pathname = ctx.path;
//获取请求文件的绝对路径
let realPath = path.join(dir,pathname);
try{
let statObj = await stat(realPath);
//如果是文件则读取文件,并且设置好相应的响应头
if (statObj.isFile()) {
ctx.set('Content-Type', mime.getType(realPath)+";charset=utf-8");
ctx.body = fs.createReadStream(realPath)
//如果不是文件,则判断是否存在index.html
} else {
let filename = path.join(realPath, 'index.html')
await stat(filename)
ctx.set('Content-Type', "text/html;charset=utf-8");
ctx.body = fs.createReadStream(filename);
}
}catch(e){
//出错直接跳过这个中间件
await next();
}
}
}
app.use(static(path.resolve(__dirname, 'public')));
app.use(router.routes());
app.listen(3000);
koa-view
использование коа-вида
Взяв в качестве примера шаблон ejs, предположим, что отрисовываемый шаблон:
//template.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<%arr.forEach(a=>{%>
<li><%=a%></li>
<%})%>
</body>
</html>
Логика отрисовки страницы:
const Koa = require('koa');
const path = require('path');
const Router = require('koa-router')
const views = require('koa-views');
let app = new Koa();
let router = new Router();
app.use(views(path.resolve(__dirname), {
//不设置的话,模板文件要使用.ejs后缀而不是.htmls后缀
map: { html: 'ejs' }
}));
router.get('/',async (ctx,next)=> {
await ctx.render('template.html',{arr:[1,2,3]})
})
app.listen(3000);
Принцип рендеринга EJS
В koa будет установлен метод рендеринга шаблона.Как правило, для рендеринга страницы будет использоваться шаблонизатор ejs:
- Соответствие <%> превращает его в ${xx}%>
- Сопоставьте <%xxxx%>, чтобы объединить содержимое xxxx в строку функции.%xxxx%>
- Затем сгенерируйте данные выполнения функции через новую строку функции Function и верните обработанную строку.
//简化渲染模板便于理解,去掉其他标签,真实渲染时,这些标签是存在的
<body>
<%arr.forEach(a=>{%>
<li><%=a%></li>
<%})%>
</body>
Функция рендеринга в ejs, упрощенная версия:
function render(r, obj) {
let head = `let str=''\r\n`;
//with可以将变量的上下文指向为obj,所以a => obj.a
head += 'with(b){\r\n'
let content = 'str+=`'
//先将匹配<%=xx%>将其变成${xx}
r = r.replace(/<%=([\s\S]*?)%>/g, function () {
return '${' + arguments[1] + '}'
});
//匹配<%xxxx%>将xxxx中的内容拼接起来变成一个函数主要逻辑
content += r.replace(/<%([\s\S]*?)%>/g, function () {
return '`\r\n' + arguments[1] + "\r\n str+=`"
});
let tail = "`\r\n} \r\n return str";
let fnStr = head + content + tail;
let fn = new Function('b', fnStr)
return fn(obj);
}
/*******************************************************************/
fn= function(b){
let str='';
with(b){
str+='<body>';
b.arr.forEach(a=>{str += '<li>${a}</li>'});
str += '</body>';
}
return str
}
Принцип коа-вида
let { promisify} = require('util');
let fs = require('fs');
let read = promisify(fs.readFile); //promise化
function views(p,opts) {
return async(ctx,next)=>{
function render(r, obj) {
let head = `let str=''\r\n`;
head += 'with(b){\r\n'
let content = 'str+=`'
r = r.replace(/<%=([\s\S]*?)%>/g, function () {
return '${' + arguments[1] + '}'
});
content += r.replace(/<%([\s\S]*?)%>/g, function () {
return '`\r\n' + arguments[1] + "\r\n str+=`"
});
let tail = "`\r\n} \r\n return str";
let fnStr = head + content + tail;
let fn = new Function('b', fnStr)
return fn(obj);
}
//在ctx上挂在render函数,读取文件模版,然后使用render函数渲染
ctx.render = async (filename,obj) => {
let realPath = path.join(p,filename);
let r = await read(realPath,'utf8');
ctx.body = render(r, obj);
}
return next();
}
}
module.exports = views;
Эпилог
В основном представлены принципы koa-view и koa-static middleware, а о других промежуточных слоях kao мы узнаем позже: