当前位置: 首页 > 工具软件 > koa-template > 使用案例 >

koa渲染html文件,koa框架会用也会写—(koa-view、koa-static)

竺捷
2023-12-01

Koa中常用的中间件:

koa-session:让无状态的http拥有状态,基于cookie实现的后台保存信息的session

koa-mysql:封装了需要用到的SQL语句

koa-mysql-session:当不想让session存储到内存,而想让session存储到mysql数据库中时使用

koa-router:后台会接受到各种请求的url,路由会根据不同的url来使用不同的处理逻辑。

koa-view:请求html页面时,后台会用模板引擎渲染数据到模板上,然后返回给后台

koa-static:请求img、js、css等文件时,不需要其他逻辑,只需要读取文件

koa-better-body:post上传文件时,解析请求体

koa系列文章:

静态资源和动态资源

在网络请求中,请求往往分成两种类型,一种是静态资源,直接从服务器的文件存储中读取,一种是动态资源,一般需要先从数据库获取数据,然后经过一定的处理,最后返回给客户端。

koa-static:用来处理静态资源的访问,因为它不涉及其他的处理过程,只是单纯的读取文件,所以单独抽离出来。

koa-view是用来将数据和模板结合渲染html页面时采用的,渲染模板的逻辑都是一样的,所以也单独抽离出来。

koa-static

判断请求的文件是否存在,如果存在读取文件返回

如果请求的文件不存在,默认返回当前文件的index.html

根据上面的思想,所以实现简单版的static,可以将static单独存在一个js文件按中,然后require进来,这样使用和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

koa-view使用

以ejs模板为例,假设要渲染的模板是:

//template.html

Document

{%>

复制代码

渲染页面的逻辑:

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中的内容拼接起来变成一个函数字符串

然后通过new Function函数字符串生成一个函数执行数据就会返回渲染后的字符串

//简化渲染模板便于理解,去掉其他标签,真实渲染时,这些标签是存在的

{%>

复制代码

ejs中的render函数,简化版本:

function render(r, obj) {

let head = `let str=''\r\n`;

//with可以将变量的上下文指向为obj,所以a => obj.a

head += 'with(b){\r\n'

let content = 'str+=`'

//先将匹配将其变成${xx}

r = r.replace(//g, function () {

return '${' + arguments[1] + '}'

});

//匹配将xxxx中的内容拼接起来变成一个函数主要逻辑

content += r.replace(//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+='

';

b.arr.forEach(a=>{str += '

${a}'});

str += '';

}

return str

}

复制代码

koa-view的原理

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(//g, function () {

return '${' + arguments[1] + '}'

});

content += r.replace(//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中间件的原理基本就介绍完了,后面一起学习kao的其他中间件:

 类似资料: