1. 程式人生 > >從零開始學習Koa(二)

從零開始學習Koa(二)

一、Koa 路由

路由(Routing)是由一個 URI(或者叫路徑)和一個特定的 HTTP 方法(GET、POST 等) 組成的,涉及到應用如何響應客戶端對某個網站節點的訪問。

通俗的講:路由就是根據不同的 URL 地址,載入不同的頁面實現不同的功能。

Koa 中的路由和 Express 有所不同,在 Express 中直接引入 Express 就可以配置路由,但是在 Koa 中我們需要安裝對應的 koa-router 路由模組來實現。

npm install --save koa-router
/**
 https://www.npmjs.com/package/koa-router

 1.安裝模組

 2.看文件使用

 */

//引入 koa模組

var Koa=require('koa');

var router = require('koa-router')();  /*引入是例項化路由** 推薦*/

//例項化
var app=new Koa();

router.get('/',async (ctx)=>{
    ctx.body="首頁";

})

router.get('/news',async (ctx)=>{
    ctx.body="新聞列表頁面";

})

router.get('/newscontent',async (ctx)=>{
    ctx.body="新聞詳情";

})


app.use(router.routes());   /*啟動路由*/
app.use(router.allowedMethods());

/*
*  router.allowedMethods()作用: 這是官方文件的推薦用法,我們可以
 看到 router.allowedMethods()用在了路由匹配 router.routes()之後,所以在當所有
 路由中介軟體最後呼叫.此時根據 ctx.status 設定 response 響應頭*/
app.listen(3002);

二、GET請求資料獲取

如果依靠ctx.request.url去手動處理路由,將會寫很多處理程式碼,這時候就需要對應的路由的中介軟體對路由進行控制,這裡介紹一個比較好用的路由中介軟體koa-router

安裝koa-router中介軟體

# koa2 對應的版本是 7.x
npm install --save [email protected]

快速使用koa-router

在 koa2 中 GET 傳值通過 request 接收,但是接收的方法有兩種:query 和 querystring。

  • query:返回的是格式化好的引數物件。
  • querystring:返回的是請求字串。

在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

/**
 https://www.npmjs.com/package/koa-router

 1.安裝模組

 2.看文件使用

 */

//引入 koa模組

var Koa=require('koa');

var router = require('koa-router')();  /*引入是例項化路由** 推薦*/

//例項化
var app=new Koa();

router.get('/',async (ctx)=>{
    ctx.body="首頁";

})

router.get('/news',async (ctx)=>{
    ctx.body="新聞列表頁面";

})
//獲取get傳值
//http://localhost:3002/newscontent?aid=123

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

    /*在 koa2 中 GET 傳值通過 request 接收,但是接收的方法有兩種:query 和 querystring。
     query:返回的是格式化好的引數物件。
     querystring:返回的是請求字串。*/

    //從ctx中讀取get傳值

    console.log(ctx.query);  //{ aid: '123' }       獲取的是物件   用的最多的方式      ******推薦

    console.log(ctx.querystring);  //aid=123&name=zhangsan      獲取的是一個字串

    console.log(ctx.url);   //獲取url地址

    //ctx裡面的request裡面獲取get傳值

    console.log(ctx.request.url);
    console.log(ctx.request.query);   //{ aid: '123', name: 'zhangsan' }  物件
    console.log(ctx.request.querystring);   //aid=123&name=zhangsan

    onst router = new Router(); router.get('/', function (ctx, next) {
    ctx.body="Hello koa";
})

//從 request 中獲取 GET 請求
    let request =ctx.request;
    let req_query = request.query;
    let req_querystring = request.querystring; //從上下文中直接獲取
    let ctx_query = ctx.query;
    let ctx_querystring =ctx.querystring; 
    ctx.body={
           url,
           req_query,
           req_querystring,
           ctx_query,
           ctx_querystring
    }

    //ctx.body="新聞詳情";

})


app.use(router.routes());   /*啟動路由*/
app.use(router.allowedMethods());
/*
*  router.allowedMethods()作用: 這是官方文件的推薦用法,我們可以
 看到 router.allowedMethods()用在了路由匹配 router.routes()之後,所以在當所有
 路由中介軟體最後呼叫.此時根據 ctx.status 設定 response 響應頭*/
app.listen(3002);

執行程式

node get.js

執行後程序後,用chrome訪問 http://localhost:3000/page/user?a=1&b=2 會出現以下情況 image

三、POST請求引數獲取

原理

對於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請求物件。

具體koa2 API文件可見 https://github.com/koajs/koa/blob/master/docs/api/context.md#ctxreq

解析出POST請求上下文中的表單資料

demo原始碼

https://github.com/ChenShenhai/koa2-note/blob/master/demo/request/post.js

// 解析上下文裡node原生請求的POST引數
function parsePostData( ctx ) {
  return new Promise((resolve, reject) => {
    try {
      let postdata = "";
      ctx.req.addListener('data', (data) => {
        postdata += data
      })
      ctx.req.addListener("end",function(){
        let parseData = parseQueryStr( postdata )
        resolve( parseData )
      })
    } catch ( err ) {
      reject(err)
    }
  })
}

// 將POST請求引數字串解析成JSON
function parseQueryStr( queryStr ) {
  let queryData = {}
  let queryStrList = queryStr.split('&')
  console.log( queryStrList )
  for (  let [ index, queryStr ] of queryStrList.entries()  ) {
    let itemList = queryStr.split('=')
    queryData[ itemList[0] ] = decodeURIComponent(itemList[1])
  }
  return queryData
}

舉個例子

原始碼在 /demos/request/post.js中

例子程式碼

const Koa = require('koa')
const app = new Koa()

app.use( async ( ctx ) => {

  if ( ctx.url === '/' && ctx.method === 'GET' ) {
    // 當GET請求時候返回表單頁面
    let html = `
      <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
  } else if ( ctx.url === '/' && ctx.method === 'POST' ) {
    // 當POST請求的時候,解析POST表單裡的資料,並顯示出來
    let postData = await parsePostData( ctx )
    ctx.body = postData
  } else {
    // 其他請求顯示404
    ctx.body = '<h1>404!!! o(╯□╰)o</h1>'
  }
})

// 解析上下文裡node原生請求的POST引數
function parsePostData( ctx ) {
  return new Promise((resolve, reject) => {
    try {
      let postdata = "";
      ctx.req.addListener('data', (data) => {
        postdata += data
      })
      ctx.req.addListener("end",function(){
        let parseData = parseQueryStr( postdata )
        resolve( parseData )
      })
    } catch ( err ) {
      reject(err)
    }
  })
}

// 將POST請求引數字串解析成JSON
function parseQueryStr( queryStr ) {
  let queryData = {}
  let queryStrList = queryStr.split('&')
  console.log( queryStrList )
  for (  let [ index, queryStr ] of queryStrList.entries()  ) {
    let itemList = queryStr.split('=')
    queryData[ itemList[0] ] = decodeURIComponent(itemList[1])
  }
  return queryData
}

app.listen(3000, () => {
  console.log('[demo] request post is starting at port 3000')
})

啟動例子

node post.js

訪問頁面

image

提交表單發起POST請求結果顯示

image

四、koa-bodyparser中介軟體

原理

對於POST請求的處理,koa-bodyparser中介軟體可以把koa2上下文的formData資料解析到ctx.request.body中

安裝koa2版本的[email protected]中介軟體

npm install --save [email protected]

舉個例子

例子程式碼

demo原始碼

https://github.com/ChenShenhai/koa2-note/blob/master/demo/request/post-middleware.js

const Koa = require('koa')
const app = new Koa()
const bodyParser = require('koa-bodyparser')

// 使用ctx.body解析中介軟體
app.use(bodyParser())

app.use( async ( ctx ) => {

  if ( ctx.url === '/' && ctx.method === 'GET' ) {
    // 當GET請求時候返回表單頁面
    let html = `
      <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
  } else if ( ctx.url === '/' && ctx.method === 'POST' ) {
    // 當POST請求的時候,中介軟體koa-bodyparser解析POST表單裡的資料,並顯示出來
    let postData = ctx.request.body
    ctx.body = postData
  } else {
    // 其他請求顯示404
    ctx.body = '<h1>404!!! o(╯□╰)o</h1>'
  }
})

app.listen(3000, () => {
  console.log('[demo] request post is starting at port 3000')
})

啟動例子

node post-middleware.js

訪問頁面

image

提交表單發起POST請求結果顯示

image