美文网首页
2023-03-28

2023-03-28

作者: Asagi浅木 | 来源:发表于2023-03-27 22:09 被阅读0次

    一、koa2 快速开始

    1、环境准备

    因为node.js v7.6.0开始完全支持async/await,不需要加flag,所以node.js环境都要7.6.0以上 node.js环境 版本v7.6以上 npm 版本3.x以上

    2、快速开始

    2.1 安装koa2

    # 初始化package.jsonnpm init# 安装koa2 npm install koa

    2.2 hello world 代码

    constKoa=require('koa')constapp=newKoa()app.use(async(ctx)=>{ctx.body='hello koa2'})app.listen(3000)console.log('[demo] start-quick is starting at port 3000')

    2.3 启动demo

    由于koa2是基于async/await操作中间件,目前node.js 7.x的harmony模式下才能使用,所以启动的时的脚本如下:

    node index.js

    二、async/await使用

    1、快速上手理解

    先复制以下这段代码,在粘贴在chrome的控制台console中,按回车键执行

    functiongetSyncTime(){returnnewPromise((resolve,reject)=>{try{letstartTime=newDate().getTime()setTimeout(()=>{letendTime=newDate().getTime()letdata=endTime-startTimeresolve(data)},500)}catch(err){reject(err)}})}asyncfunctiongetSyncData(){lettime=awaitgetSyncTime()letdata=`endTime - startTime = ${time}`returndata}asyncfunctiongetData(){letdata=awaitgetSyncData()console.log(data)}getData()

    2、从上述例子可以看出 async/await 的特点:

    可以让异步逻辑用同步写法实现

    最底层的await返回需要是Promise对象

    可以通过多层 async function 的同步写法代替传统的callback嵌套

    三、koa2简析结构

    1、源码文件

    ├── lib │ ├── application.js │ ├── context.js │ ├── request.js │ └── response.js └── package.json

    这个就是 GitHubhttps://github.com/koajs/koa上开源的koa2源码的源文件结构,核心代码就是lib目录下的四个文件

    application.js 是整个koa2 的入口文件,封装了context,request,response,以及最核心的中间件处理流程。

    context.js 处理应用上下文,里面直接封装部分request.js和response.js的方法

    request.js 处理http请求

    response.js 处理http响应

    2、koa2特性

    只提供封装好http上下文、请求、响应,以及基于async/await的中间件容器。

    利用ES7的async/await的来处理传统回调嵌套问题和代替koa@1的generator,但是需要在node.js 7.x的harmony模式下才能支持async/await。

    中间件只支持 async/await 封装的,如果要使用koa@1基于generator中间件,需要通过中间件koa-convert封装一下才能使用。

    四、koa中间件开发和使用

    koa v1和v2中使用到的中间件的开发和使用

    generator 中间件开发在koa v1和v2中使用

    async await 中间件开发和只能在koa v2中使用

    1、generator中间件开发

    1.1 generator中间件开发

    generator中间件返回的应该是function * () 函数

    /* ./middleware/logger-generator.js */functionlog(ctx){console.log(ctx.method,ctx.header.host+ctx.url)}module.exports=function(){returnfunction*(next){// 执行中间件的操作log(this)if(next){yieldnext}}}

    1.2 generator中间件在koa@1中的使用

    generator 中间件在koa v1中可以直接use使用

    constkoa=require('koa')// koa v1constloggerGenerator=require('./middleware/logger-generator')constapp=koa()app.use(loggerGenerator())app.use(function*(){this.body='hello world!'})app.listen(3000)console.log('the server is starting at port 3000')

    1.3 generator中间件在koa@2中的使用

    generator 中间件在koa v2中需要用koa-convert封装一下才能使用

    constKoa=require('koa')// koa v2constconvert=require('koa-convert')constloggerGenerator=require('./middleware/logger-generator')constapp=newKoa()app.use(convert(loggerGenerator()))app.use((ctx)=>{ctx.body='hello world!'})app.listen(3000)console.log('the server is starting at port 3000')

    2、async中间件开发

    2.1 async 中间件开发

    /* ./middleware/logger-async.js */functionlog(ctx){console.log(ctx.method,ctx.header.host+ctx.url)}module.exports=function(){returnasyncfunction(ctx,next){log(ctx);awaitnext()}}

    2.2 async 中间件在koa@2中使用

    async 中间件只能在 koa v2中使用

    constKoa=require('koa')// koa v2constloggerAsync=require('./middleware/logger-async')constapp=newKoa()app.use(loggerAsync())app.use((ctx)=>{ctx.body='hello world!'})app.listen(3000)console.log('the server is starting at port 3000')

    Ⅱ、路由

    一、koa2 原生路由实现

    1、简单例子

    constKoa=require('koa')constapp=newKoa()app.use(async(ctx)=>{leturl=ctx.request.url  ctx.body=url})app.listen(3000)

    访问http://localhost:3000/hello/world页面会输出 /hello/world,也就是说上下文的请求request对象中url之就是当前访问的路径名称,可以根据ctx.request.url 通过一定的判断或者正则匹配就可以定制出所需要的路由。

    2、定制化的路由

    demo源码

    https://github.com/ChenShenhai/koa2-note/tree/master/demo/route-simple

    2.1 源码文件目录

    .├── index.js├── package.json└── view    ├── 404.html    ├── index.html    └── todo.html

    2.2 demo源码

    constKoa=require('koa')constfs=require('fs')constapp=newKoa()/**

    * 用Promise封装异步读取文件方法

    * @param  {string} page html文件名称

    * @return {promise}     

    */functionrender(page){returnnewPromise((resolve,reject)=>{letviewUrl=`./view/${page}`fs.readFile(viewUrl,"binary",(err,data)=>{if(err){reject(err)}else{resolve(data)}})})}/**

    * 根据URL获取HTML内容

    * @param  {string} url koa2上下文的url,ctx.url

    * @return {string}    获取HTML文件内容

    */asyncfunctionroute(url){letview='404.html'switch(url){case'/':view='index.html'breakcase'/index':view='index.html'breakcase'/todo':view='todo.html'breakcase'/404':view='404.html'breakdefault:break}lethtml=awaitrender(view)returnhtml}app.use(async(ctx)=>{leturl=ctx.request.urllethtml=awaitroute(url)ctx.body=html})app.listen(3000)console.log('[demo] route-simple is starting at port 3000')

    2.3 运行demo

    执行运行脚本

    node -harmony index.js

    二、koa-router中间件

    如果依靠ctx.request.url去手动处理路由,将会写很多处理代码,这时候就需要对应的路由的中间件对路由进行控制,这里介绍一个比较好用的路由中间件koa-router

    1、安装koa-router中间件

    # koa2 对应的版本是 7.xnpm install --save koa-router@7

    2、快速使用koa-router

    constKoa=require('koa')constfs=require('fs')constapp=newKoa()constRouter=require('koa-router')lethome=newRouter()// 子路由1home.get('/',async(ctx)=>{lethtml=`    <ul>

          <li><a href="/page/helloworld">/page/helloworld</a></li>

          <li><a href="/page/404">/page/404</a></li>

        </ul>

      `ctx.body=html})// 子路由2letpage=newRouter()page.get('/404',async(ctx)=>{ctx.body='404 page!'}).get('/helloworld',async(ctx)=>{ctx.body='helloworld page!'})// 装载所有子路由letrouter=newRouter()router.use('/',home.routes(),home.allowedMethods())router.use('/page',page.routes(),page.allowedMethods())// 加载路由中间件app.use(router.routes()).use(router.allowedMethods())app.listen(3000,()=>{console.log('[demo] route-use-middleware is starting at port 3000')})

    Ⅲ、请求数据获取

    一、GET请求数据获取

    1、使用方法

    在koa中,获取GET请求数据源头是koa中request对象中的query方法或querystring方法,query返回是格式化好的参数对象,querystring返回的是请求字符串,由于ctx对request的API有直接引用的方式,所以获取GET请求数据有两个途径。

    是从上下文中直接获取 请求对象ctx.query,返回如 { a:1, b:2 } 请求字符串 ctx.querystring,返回如 a=1&b=2

    是从上下文的request对象中获取 请求对象ctx.request.query,返回如 { a:1, b:2 } 请求字符串 ctx.request.querystring,返回如 a=1&b=2

    2、举个例子

    2.1 例子代码

    constKoa=require('koa')constapp=newKoa()app.use(async(ctx)=>{leturl=ctx.url// 从上下文的request对象中获取letrequest=ctx.requestletreq_query=request.queryletreq_querystring=request.querystring// 从上下文中直接获取letctx_query=ctx.queryletctx_querystring=ctx.querystring  ctx.body={url,req_query,req_querystring,ctx_query,ctx_querystring}})app.listen(3000,()=>{console.log('[demo] request get is starting at port 3000')})

    2.2 执行程序

    node get.js

    二、POST请求参数获取

    1、原理

    对于POST请求的处理,koa2没有封装获取参数的方法,需要通过解析上下文context中的原生node.js请求对象req,将POST表单数据解析成query string(例如:a=1&b=2&c=3),再将query string 解析成JSON格式(例如:{"a":"1", "b":"2", "c":"3"})

    注意:ctx.request是context经过封装的请求对象,ctx.req是context提供的node.js原生HTTP请求对象,同理ctx.response是context经过封装的响应对象,ctx.res是context提供的node.js原生HTTP请求对象。

    解析出POST请求上下文中的表单数据

    // 解析上下文里node原生请求的POST参数functionparsePostData(ctx){returnnewPromise((resolve,reject)=>{try{letpostdata="";ctx.req.addListener('data',(data)=>{postdata+=data})ctx.req.addListener("end",function(){letparseData=parseQueryStr(postdata)resolve(parseData)})}catch(err){reject(err)}})}// 将POST请求参数字符串解析成JSONfunctionparseQueryStr(queryStr){letqueryData={}letqueryStrList=queryStr.split('&')console.log(queryStrList)for(let[index,queryStr]ofqueryStrList.entries()){letitemList=queryStr.split('=')queryData[itemList[0]]=decodeURIComponent(itemList[1])}returnqueryData}

    2、举个例子

    2.1 例子代码

    constKoa=require('koa')constapp=newKoa()app.use(async(ctx)=>{if(ctx.url==='/'&&ctx.method==='GET'){// 当GET请求时候返回表单页面lethtml=`      <h1>koa2 request post demo</h1>

          <form method="POST" action="/">

            <p>userName</p>

            <input name="userName" /><br/>

            <p>nickName</p>

            <input name="nickName" /><br/>

            <p>email</p>

            <input name="email" /><br/>

            <button type="submit">submit</button>

          </form>

        `ctx.body=html}elseif(ctx.url==='/'&&ctx.method==='POST'){// 当POST请求的时候,解析POST表单里的数据,并显示出来letpostData=awaitparsePostData(ctx)ctx.body=postData}else{// 其他请求显示404ctx.body='<h1>404!!! o(╯□╰)o</h1>'}})// 解析上下文里node原生请求的POST参数functionparsePostData(ctx){returnnewPromise((resolve,reject)=>{try{letpostdata="";ctx.req.addListener('data',(data)=>{postdata+=data})ctx.req.addListener("end",function(){letparseData=parseQueryStr(postdata)resolve(parseData)})}catch(err){reject(err)}})}// 将POST请求参数字符串解析成JSONfunctionparseQueryStr(queryStr){letqueryData={}letqueryStrList=queryStr.split('&')console.log(queryStrList)for(let[index,queryStr]ofqueryStrList.entries()){letitemList=queryStr.split('=')queryData[itemList[0]]=decodeURIComponent(itemList[1])}returnqueryData}app.listen(3000,()=>{console.log('[demo] request post is starting at port 3000')})

    2.2 启动例子

    node post.js

    三、koa-bodyparser中间件

    1、原理

    对于POST请求的处理,koa-bodyparser中间件可以把koa2上下文的formData数据解析到ctx.request.body中

    安装koa2版本的koa-bodyparser@3中间件

    npm install --save koa-bodyparser@3

    2、举个例子

    2.1 例子代码

    constKoa=require('koa')constapp=newKoa()constbodyParser=require('koa-bodyparser')// 使用ctx.body解析中间件app.use(bodyParser())app.use(async(ctx)=>{if(ctx.url==='/'&&ctx.method==='GET'){// 当GET请求时候返回表单页面lethtml=`      <h1>koa2 request post demo</h1>

          <form method="POST" action="/">

            <p>userName</p>

            <input name="userName" /><br/>

            <p>nickName</p>

            <input name="nickName" /><br/>

            <p>email</p>

            <input name="email" /><br/>

            <button type="submit">submit</button>

          </form>

        `ctx.body=html}elseif(ctx.url==='/'&&ctx.method==='POST'){// 当POST请求的时候,中间件koa-bodyparser解析POST表单里的数据,并显示出来letpostData=ctx.request.body    ctx.body=postData}else{// 其他请求显示404ctx.body='<h1>404!!! o(╯□╰)o</h1>'}})app.listen(3000,()=>{console.log('[demo] request post is starting at port 3000')})

    2.2 启动例子

    node post-middleware.js

    Ⅳ、静态资源加载

    koa-static中间件使用

    1、使用例子

    constKoa=require('koa')constpath=require('path')conststatic=require('koa-static')constapp=newKoa()// 静态资源目录对于相对入口文件index.js的路径conststaticPath='./static'app.use(static(path.join(__dirname,staticPath)))app.use(async(ctx)=>{ctx.body='hello world'})app.listen(3000,()=>{console.log('[demo] static-use-middleware is starting at port 3000')})

    Ⅴ、模板引擎

    koa2加载模板引擎

    1、快速开始

    1.1 安装模块

    # 安装koa模板使用中间件npm install --save koa-views# 安装ejs模板引擎npm install --save ejs

    1.2 使用模板引擎

    文件目录

    ├── package.json├── index.js└── view    └── index.ejs

    ./index.js文件

    constKoa=require('koa')constviews=require('koa-views')constpath=require('path')constapp=newKoa()// 加载模板引擎app.use(views(path.join(__dirname,'./view'),{extension:'ejs'}))app.use(async(ctx)=>{lettitle='hello koa2'awaitctx.render('index',{title,})})app.listen(3000)

    ./view/index.ejs 模板

    <!DOCTYPE html><html><head><title><%= title %></title></head><body><h1><%= title %></h1><p>EJS Welcome to <%= title %></p></body></html>

    0人点赞

    NodeJS

    作者:硅谷干货

    链接:https://www.jianshu.com/p/920ad3e248ec

    来源:简书

    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    相关文章

      网友评论

          本文标题:2023-03-28

          本文链接:https://www.haomeiwen.com/subject/quxtddtx.html