• wordpress CMS主题:ssmay主题 wordpress CMS主题:ssmay主题
  • 首页 > 前端开发 > koa框架会用也会写—(koa-view、koa-static)

    koa框架会用也会写—(koa-view、koa-static)

    作者: 分类:前端开发 点击: 42 次
    wordpress CMS主题:ssmay主题

      扫描下面的二维码,“关注”我的头条号,我会每天更新免费视频课程。

      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,如果存在返回当前文件下的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)
            } else {
                  //如果不是文件,则判断是否存在index.html
                  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
      
      <!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%>将其变成${xx}
      • 匹配<%xxxx%>将xxxx中的内容拼接起来变成一个函数字符串
      • 然后通过new Function函数字符串生成一个函数执行数据就会返回渲染后的字符串
      //简化渲染模板便于理解,去掉其他标签,真实渲染时,这些标签时存在的
      <body>
        <%arr.forEach(a=>{%>
          <li><%=a%></li>
        <%})%>
      </body>
      

      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%>将其变成${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
      //}  
      

      koa-view的原理

      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函数,读取文件,然后渲染
          ctx.render = async (filename,obj) => {
              let realPath = path.join(p,filename);
              let { promisify} = require('util');
              let fs = require('fs');
              let read = promisify(fs.readFile);  //promise化
              let r = await read(realPath,'utf8');
              ctx.body = render(r, obj);
          }
          return next();
        }
      }
      module.exports = views;
      

      渲染页面的逻辑:

      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), {
        map: { html: 'ejs' }  
      }));
      router.get('/',async (ctx,next)=> {
       await ctx.render('template.html',{arr:[1,2,3]})
      })
      app.listen(3000);
      

      结语

      koa-router中间件的原理基本就介绍完了,后面一起学习kao的其他中间件:

      本文转载于:猿2048koa框架会用也会写—(koa-view、koa-static)



      欢迎“关注”我的头条号,我会每天更新免费视频课程。

      头条二维码
      关注我的头条号
      头条二维码
      加入我的QQ群

    文章作者:sunny
    本文地址:http://wanlimm.com/77202006218345.html
    版权所有 © 转载时必须以链接形式注明作者和原始出处!

    上一篇:
    下一篇:
    wordpress CMS主题:ssmay主题

    或许你会感兴趣的文章:

    发表评论

    电子邮件地址不会被公开。 必填项已用*标注

    This site uses Akismet to reduce spam. Learn how your comment data is processed.