【從前端到全棧】- koa快速入門指南

前言

隨着技術的不斷髮展,前端工程師也被賦予了愈來愈多的職責。再也不是從前只須要切個圖,加個css樣式就能完成任務的切圖仔了。接下來這篇文章,完成一個簡單的登陸註冊,能讓你快速上手,成爲一個‘小全棧工程師’,here we go !javascript

15371488705139

koa快速開始

安裝

  • 由於node.js v7.6.x已經徹底支持async/await語法,因此請保證node的版本在7.6以上
  • 推薦一個node的多版本管理工具:nvm。如何安裝這裏再也不贅述,網上的教程有不少css

// 初始化package.json
npm init

// 安裝koa2 
npm install koa

一個hello world

新建一個index.js,敲上如下代碼html

//index.js

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

app.use( async (ctx, next) => {
  ctx.response.body = '你好,我是內地吳彥祖'
})

app.listen(3333, ()=>{
  console.log('server is running at http://localhost:3333')
})

在咱們的命令行敲上前端

node index.js

就能夠看到運行結果啦:java

15371507388772

幾個核心概念

中間件好基友ctx和next

在上面的代碼中,咱們能夠看到app.use後面使用了2個參數,ctxnext,下面咱們介紹一個這哥倆到底幹嗎的node

ctx

ctx做爲上下文使用,Koa將 node 的 request, response 對象封裝進一個單獨對象。即ctx.requestctx.response。Koa 內部又對一些經常使用的屬性或者方法作了代理操做,使得咱們能夠直接經過 ctx 獲取。好比,ctx.request.url 能夠寫成 ctx.urlgit

next

next 參數的做用是將處理的控制權轉交給下一個中間件github

15371520197565

經典的洋蔥圖概念能很好的解釋next的執行,請求從最外層進去,又從最裏層出來。咱們看一個例子chrome

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

app.use(async (ctx, next)=>{
  let startTime = new Date().getTime()
  await next()
  let endTime = new Date().getTime()
  console.log(`這次的響應時間爲:${endTime - startTime}ms`)
})

app.use(async (ctx, next) => {
  console.log('111, 而後doSomething')
  await next()
  console.log('111 end')
})

app.use(async (ctx, next) => {
  console.log('222, 而後doSomething')
  await next()
  console.log('222 end')
})

app.use(async (ctx, next) => {
  console.log('333, 而後doSomething')
  await next()
  console.log('333 end')
})

app.listen(3333, ()=>{
  console.log('server is running at http://localhost:3333')
})

看一下運行結果:npm

15371528106452

若是將‘222’函數的next()去掉的話,會發生什麼呢?

15371529369320

能夠看到,後面的‘333’中間件直接不執行了。因此中間件的順序對next的執行有很大的影響

路由 koa-router

咱們經常使用koa-router來處理URL

安裝

npm i koa-router --save

看一個例子:

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

const router = new Router()

router.get('/', async (ctx, next) => {
  ctx.body = '你好,我這裏是index頁'
})

router.get('/user', async (ctx, next) => {
  ctx.body = '你好,我這裏是user頁'
})

router.get('/error', async (ctx, next) => {
  ctx.body = '你好,我這裏是error頁'
})

app.use(router.routes())

app.listen(3333, ()=>{
  console.log('server is running at http://localhost:3333')
})

15371540305250

15371540448439
15371540585094

koa-router也支持嵌套寫法,經過一個總路由裝載全部子路由,也很是的方便。看一個例子:

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

// 子路由1
let oneRouter = new Router()

oneRouter.get('/', async (ctx, next) => {
  ctx.body = '你好,我這裏是oneRouter頁'
})

// 子路由2
let twoRouter = new Router()

twoRouter.get('/', async (ctx, next) => {
  ctx.body = '你好, 我這裏是twoRouter頁'
}).get('/home', async (ctx , next) => {
  ctx.body = '你好, 我這裏是home頁'
})

// 裝載全部子路由
let indexRouter = new Router()

indexRouter.use('/one',oneRouter.routes(), oneRouter.allowedMethods())
indexRouter.use('/two',twoRouter.routes(), twoRouter.allowedMethods())

app
  .use(indexRouter.routes())
  .use(indexRouter.allowedMethods())

app.listen(3333, ()=>{
  console.log('server is running at http://localhost:3333')
})

看一下運行結果:

15371560100616
15371560354693
15371560521654

獲取請求數據

koa-router提供了常見的 .get .put .post .del 接口來處理各類需求。實際開發中咱們用的比較多的是get和post,咱們來看看get例子:

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

router.get('/data', async (ctx , next)=> {
  let url = ctx.url

  // 從ctx的request中拿到咱們想要的數據
  let data = ctx.request.query
  let dataQueryString = ctx.request.querystring

  ctx.body = {
    url,
    data,
    dataQueryString
  }
})

app.use(router.routes())

app.listen(3333, ()=>{
  console.log('server is running at http://localhost:3333')
})

在瀏覽器裏輸入http://localhost:3333/data?user=wuyanzu&id=123456 ,能夠看到運行結果

15371636443212

能夠看到區別,.query返回的結果是對象,而.querystring返回的是字符串,這個很好理解。(chrome插件顯示成json格式)

若是聽從 RESTful 規範,好比請求要以 '/user/:id'的方式發出的話,咱們能夠用下面的例子來獲取到想要的數據

添加代碼

router.get('/data/:id', async (ctx, next) => {

  // 也從ctx中拿到咱們想要的數據,不過使用的是params對象
  let data = ctx.params

  ctx.body = data
})

瀏覽器運行 http://localhost:3333/data/4396 看到結果

15371643392037

接下來咱們看看post的例子

咱們經常使用的請求post,它的數據是放在body當中的。這個時候就推薦一個很是經常使用且好用的中間件-koa-bodyparser

首先安裝

npm i koa-bodyparser --save

而後咱們在剛纔的代碼裏添加

router.get('/post', async (ctx, next) => {
    // 模擬一段提交頁面
  let html = `    
    <form action="/post/result" method="post">
        <p>你長的最像哪位明星</p>
        <input name="name" type="text" placeholder="請輸入名字:"/> 
        <br/>
        <p>輸入一段你知道的車牌號</p>
        <input name="num" type="text" placeholder="請輸入車牌號:"/>
        <br/> 
        <button>肯定不改了哦</button>
     </form> `
  ctx.body = html
})

router.post('/post/result', async (ctx, next) => {
  // 咱們能夠從ctx的request.body拿到提交上來的數據
  let {name, num} = ctx.request.body

  if (name && num) {
    ctx.body = `hello,你最像的明星是:${name},ch你知道的車牌號是:${num}`
  } else {
    ctx.body = '啊哦~你填寫的信息有誤'
  }

})

看一下運行結果

2018-09-17 14 26 24

cache

koa操做cookie是很是方便的,也是從上下文ctx中獲取。

  • ctx.cookies.get(name, [options]) 讀取上下文請求中的cookie
  • ctx.cookies.set(name, value, [options]) 在上下文中寫入cookie

在咱們剛纔的post請求的代碼中加入:

router.post('/post/result', async (ctx, next) => {
  // 咱們能夠從ctx的request.body拿到提交上來的數據
  let {name, num} = ctx.request.body

  if (name && num) {
    ctx.body = `hello,你最像的明星是:${name},ch你知道的車牌號是:${num}`
    ctx.cookies.set(
      'xunleiCode',num,
      {
        domain: 'localhost',  // 寫cookie所在的域名
        path: '/post/result',       // 寫cookie所在的路徑
        maxAge: 10 * 60 * 1000, // cookie有效時長
        expires: new Date('2018-09-17'),  // cookie失效時間
        httpOnly: false,  // 是否只用於http請求中獲取
        overwrite: false  // 是否容許重寫
      }
    )
  } else {
    ctx.body = '啊哦~你填寫的信息有誤'
  }

})

看一下運行結果:
15371681204265
15371681313023

koa操做session的話,須要用到koa-session,🌰:

const session = require('koa-session')

app.keys = ['some secret hurr'];
const CONFIG = {
  key: 'koa:sess',   //cookie key (default is koa:sess)
  maxAge: 86400000,  // cookie的過時時間 maxAge in ms (default is 1 days)
  overwrite: true,  //是否能夠overwrite    (默認default true)
  httpOnly: true, //cookie是否只有服務器端能夠訪問 httpOnly or not (default true)
  signed: true,   //簽名默認true
  rolling: false,  //在每次請求時強行設置cookie,這將重置cookie過時時間(默認:false)
  renew: false,  //(boolean) renew session when session is nearly expired,
};
app.use(session(CONFIG, app));

小結

在涉及到本身沒有接觸過的領域時,我一直推崇先看看要怎麼玩,等本身會玩了之後,再看看「究竟」怎麼玩。咱們經過上面的代碼和描述,已經對koa及node有一個初步的印象和概念。下篇文章咱們會有中間件的拆分,單元測試,記錄日誌,管理規範等。讓咱們共同成長!

廣而告之

本文發佈於薄荷前端週刊,歡迎Watch & Star ★,轉載請註明出處。

歡迎討論,點個贊再走吧 。◕‿◕。 ~

相關文章
相關標籤/搜索