koa2

1.搭建一个最简单的KOA服务器。

们初始化生产package.json 文件 

npm init - y

生成package.json后,安装koa包


index.js

const Koa = require("koa")
const app = new Koa();
app.use(async(ctx)=>{
ctx.body = "hello,world"
})

app.listen(3000);
console.log("app is start");



npm init - y

2.接受get请求。

在koa2中GET请求通过request接收,但是接受的方法有两种:query和querystring。

  • query:返回的是格式化好的参数对象。
  • querystring:返回的是请求字符串。

如前端发出 http://127.0.0.1:3000/?a=1&id=2

demo1.js

const koa = require("koa");
const app = new koa();
app.use(async(ctx)=>{
let url = ctx.url;
//从request中获取GET请求
let request = ctx.request;
let req_query = request.query;
let req_querystring = request.querystring;
//从上下文中获取GET请求
let ctx_query = ctx.query;
let ctx_querystring = ctx.querystring;
ctx.body = { //打印到页面上
url,
req_query,
req_querystring,
ctx_query,
ctx_querystring
}
})
app.listen(3000,()=>{
console.log("app is start");
});

输出JSON:

{"url":"/?a=1&id=2","req_query":{"a":"1","id":"2"},"req_querystring":"a=1&id=2","ctx_query":{"a":"1","id":"2"},

"ctx_querystring":"a=1&id=2"}

ctx 对象:

{ method: 'GET',
     url: '/',
     header:
      { host: '127.0.0.1:3000',
        connection: 'keep-alive',
        'upgrade-insecure-requests': '1',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
        accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
        dnt: '1',
        'accept-encoding': 'gzip, deflate, sdch, br',
        'accept-language': 'zh-CN,zh;q=0.8' } },
  response: { status: 404, message: 'Not Found', header: {} },
  app: { subdomainOffset: 2, proxy: false, env: 'development' },
  originalUrl: '/',
  req: '<original node req>',
  res: '<original node res>',
  socket: '<original node socket>' }
{ request:
   { method: 'GET',
     url: '/favicon.ico',
     header:
      { host: '127.0.0.1:3000',
        connection: 'keep-alive',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
        accept: 'image/webp,image/*,*/*;q=0.8',
        dnt: '1',
        referer: 'http://127.0.0.1:3000/',
        'accept-encoding': 'gzip, deflate, sdch, br',
        'accept-language': 'zh-CN,zh;q=0.8' } },
  response: { status: 404, message: 'Not Found', header: {} },
  app: { subdomainOffset: 2, proxy: false, env: 'development' },
  originalUrl: '/favicon.ico',
  req: '<original node req>',
  res: '<original node res>',
  socket: '<original node socket>' }

3.接受POST请求

对于POST请求的处理,Koa2没有封装方便的获取参数的方法,需要通过解析上下文context中的原生node.js请求对象req来获取。

获取Post请求的步骤:

  1. 解析上下文ctx中的原生nodex.js对象req。
  2. 将POST表单数据解析成query string-字符串.(例如:user=jspang&age=18)
  3. 将字符串转换成JSON格式。

ctx.request和ctx.req的区别

  • ctx.request:是Koa2中context经过封装的请求对象,它用起来更直观和简单。
  • ctx.req:是context提供的node.js原生HTTP请求对象。这个虽然不那么直观,但是可以得到更多的内容,适合我们深度编程。

ctx.method 得到请求类型

Koa2中提供了ctx.method属性,可以轻松的得到请求的类型,然后根据请求类型编写不同的相应方法,这在工作中非常常用。我们先来作个小例子,根据请求类型获得不同的页面内容。GET请求时得到表单填写页面,POST请求时,得到POST处理页面。


demo2.js

const koa = require("koa");
const app = new koa();
app.use(async(ctx)=>{
    if(ctx.url==='/' && ctx.method==="GET"){
        let html = `<form method="post" action="/">
        <p>usename:<input type="text" name="usename"></p>
        <p>age:<input type="text" name="age"></p>
        <p>site:<input type="text" name="site"></p>
        <button type="submit" >submit</button>
        </form>`;
        ctx.body=html;
    }else if(ctx.url==='/' && ctx.method==="POST"){
       //ctx.body = "POST"
       let postData =await parsePostData(ctx);
       ctx.body = postData
    }else{
        ctx.body = "404"
    }
})

function parsePostData(ctx){
  return new Promise((resolve,reject)=>{
      try{
          let postdata = '';
          ctx.req.addListener("data",(data)=>{
            postdata += data;
          });
          ctx.req.on('end',function(){//监听数据结束时,对数据传出去
            let postData = parseQuerystr(postdata)
            resolve(postData)
          })
      }catch(error){
        reject(error)
      }
  })

}

function parseQuerystr(querystr){
    let queryData = {};
    let queryStrlist = querystr.split("&");
    
    for(let itemquery of queryStrlist){
        let queryDatalist = itemquery.split("=");
       
        queryData[queryDatalist[0]] =decodeURIComponent(queryDatalist[1]) ;
    }
    return(queryData)
 }

app.listen(3000,()=>{
    console.log("domo2 server is start");
})

输出: { "usename" : "long" , "age" : " 30 " , "site" : "www.baidu.com" }


4.koa-bodyparser中间件

npm install --save koa-bodyparser

引入使用

安装完成后,需要在代码中引入并使用。我们在代码顶部用require进行引入。

然后进行使用,如果不使用是没办法调用的,使用代码如下。


在代码中使用后,直接可以用ctx.request.body进行获取POST请求参数,中间件自动给我们作了解析。

demo3.js

const koa = require("koa");
const app = new koa();
const koaBody = require("koa-bodyparser")
app.use(koaBody());

app.use(async(ctx)=>{
    if(ctx.url==='/' && ctx.method==="GET"){
        let html = `<form method="post" action="/">
        <p>usename:<input type="text" name="usename"></p>
        <p>age:<input type="text" name="age"></p>
        <p>site:<input type="text" name="site"></p>
        <button type="submit" >submit</button>
        </form>`;
        ctx.body=html;
    }else if(ctx.url==='/' && ctx.method==="POST"){
       //ctx.body = "POST"
       let postData =ctx.request.body;
       ctx.body = postData
    }else{
        ctx.body = "404"
    }
})
{ "usename" : "long1" , "age" : " 30 " , "site" : "www.baidu.com" }


5Koa2原生路由实现

ctx.request.url 获取路径 如:/name

原生路由的实现需要引入fs模块来读取文件。然后再根据路由的路径去读取,最后返回给页面,进行渲染。

domo4.js

const koa = require("koa")
const app = new koa();
const fs = require("fs");

function render(page){
    return new Promise((resolve,reject)=>{
        let pageURL = './page/'+page;
       
        fs.readFile(pageURL,'binary',(err,data)=>{
            if(err){
                reject(err);
            }else{
                
                resolve(data);
            }
        })
    })
}

async function route(url){
   let page = '404.html';
   switch(url){
       case '/':
         page = 'index.html';
         break;
       case '/index.html':
         page = 'index.html';
         break;
       case '/todo.html':
         page = 'todo.html';
         break;
       case '/404.html':
         page = '404.html';
         break;
       default:
         break;
   }
   let html =await render(page);
   
   return html
}

app.use(async(ctx)=>{
    let url = ctx.request.url;
    let html = await route(url)
    console.log(html)
    ctx.body = html;
});

app.listen(3000)

6.Koa-router中间件

安装koa-router中间件

demo5.js
const Koa = require('koa');
const Router = require('koa-router');
 
const app = new Koa();
const router = new Router();
 
router.get('/', function (ctx, next) {
    ctx.body="Hello JSPang";
})
.get('/todo',(ctx,next)=>{
    ctx.body="Todo page"
});
 
app
  .use(router.routes())
  .use(router.allowedMethods());
  app.listen(3000,()=>{
      console.log('starting at port 3000');
  });

设置前缀

有时候我们想把所有的路径前面都再加入一个级别,比如原来我们访问的路径是http://127.0.0.1:3000/todo,现在我们希望在所有的路径前面都加上一个jspang层级,把路径变成http://127.0.0.1:3000/jspang/todo.这时候就可以使用层级来完成这个功能。路由在创建的时候是可以指定一个前缀的,这个前缀会被至于路由的最顶层,也就是说,这个路由的所有请求都是相对于这个前缀的。

写上这句代码,这时候你的访问路径就加了一个层级jspang。可以在浏览器中输入:http://127.0.0.1:3000/js/测试一下。


路由层级

例如这种写法装载路由层级,这里的router相当于父级:router.use(‘/page’, page.routes(), page.allowedMethods())

代码如下:我们声明了两个路由,第一个是home,第二个是page.然后通过use赋予不同的前层级。

demo6.js

const koa = require('koa');
const app = new koa();
const Router = require("koa-router");
//主路由


let home = new Router();
home.get('/js',async(ctx)=>{
    ctx.body = "js";
}).get('/vue',async(ctx)=>{
    ctx.body = "vue"
});

let page = new Router();
page.get('/js',async(ctx)=>{
    ctx.body = "js";
}).get('/vuex',async(ctx)=>{
    ctx.body = "vuex"
    });

let router = new Router();
router.use('/home',home.routes(),home.allowedMethods());
router.use('/page',page.routes(),page.allowedMethods());


app
   .use(router.routes())
   .use(router.allowedMethods());

app.listen(3000,()=>{console.log('app is start')});

参数

demo7.js

const koa = require('koa');
const Router = require("koa-router");
const app = new koa();
const router = new Router();

router.get('/',(ctx,next)=>{

    ctx.body = ctx.query;
    
})

app.use(router.routes()).use(router.allowedMethods());

app.listen(3000,()=>{
    console.log('app is start');
});
地址栏:http://127.0.0.1:3000/?a=1&v=2

输出:{"a":"1","v":"2"}

7.Koa2中使用cookie


开发中制作登录和保存用户信息在本地,最常用的就是cookie操作。比如我们在作一个登录功能时,希望用户在接下来的一周内都不需要重新登录就可以访问资源,这时候就需要我们操作cookie来完成我们的需求。koa的上下文(ctx)直接提供了读取和写入的方法。

  • ctx.cookies.get(name,[optins]):读取上下文请求中的cookie。
  • ctx.cookies.set(name,value,[options]):在上下文中写入cookie。

demo8.js

const koa = require("koa");
const app = new koa();
app.use(async(ctx)=>{
if(ctx.url==="/index"){
ctx.cookies.set('name','johnson',{
domain:'127.0.0.1',
//path:'/index',
maxAge:1000*60*60*60,
expires:new Date("2018-12-1"),
httpOnly:false,
overwrite:false
});
ctx. body= "cookies is OK"
} else{
ctx. body= "hello.world";
if( ctx. cookies. get( "name"))
{
ctx. body= ctx. cookies. get( "name")
} else{
ctx. body= "no cookie"
}
}
})
app. listen( 3000,() =>{
console. log( "app is start");
});

ookie选项

比如我们要存储用户名,保留用户登录状态时,你可以选择7天内不用登录,也可以选择30天内不用登录。这就需要在写入是配置一些选项:

  • domain:写入cookie所在的域名
  • path:写入cookie所在的路径
  • maxAge:Cookie最大有效时长
  • expires:cookie失效时间
  • httpOnly:是否只用http请求中获得
  • overwirte:是否允许重写

8.EJS模板

安装中间件

在koa2中使用模板机制必须依靠中间件,我们这里选择koa-views中间件,先使用npm来进行安装。

安装ejs模板引擎

ejs是个著名并强大的模板引擎,可以单独安装。很多开源软件都采用了ejs模板引擎。

编写模板

安装好ejs模板引擎后,就可以编写模板了,为了模板统一管理,我们新建一个view的文件夹,并在它下面新建index.ejs文件。

views/index.ejs

详细解释在视频中讲解。

编写koa文件

有了模板文件,我们需要在js文件中配置并渲染。


9.访问静态资源

安装koa-static:

使用npm进行安装中间件,讲课时使用的是4.0.2版本。

新建static文件夹

然后在static文件中放入图片,css和js文件。


const Koa = require("koa");
const app = new Koa();
const static = require('koa-static');
const path = require('path');

const staticPath = './static'

app.use(static(path.join(__dirname,staticPath)));

app.use(async(ctx)=>{
    ctx.body = 'hello';
});

app.listen(3000,()=>{
    console.log('app ok')
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值