【从前端到全栈】- koa快速入门指南
前言
隨著技術(shù)的不斷發(fā)展,前端工程師也被賦予了越來(lái)越多的職責(zé)。不再是從前只需要切個(gè)圖,加個(gè)css樣式就能完成任務(wù)的切圖仔了。接下來(lái)這篇文章,完成一個(gè)簡(jiǎn)單的登錄注冊(cè),能讓你快速上手,成為一個(gè)‘小全棧工程師’,here we go !
koa快速開始
安裝
- 因?yàn)閚ode.js v7.6.x已經(jīng)完全支持async/await語(yǔ)法,所以請(qǐng)保證node的版本在7.6以上
-
推薦一個(gè)node的多版本管理工具:nvm。如何安裝這里不再贅述,網(wǎng)上的教程有很多
- https://github.com/creationix...
一個(gè)hello world
新建一個(gè)index.js,敲上以下代碼
//index.jsconst Koa = require('koa') const app = new Koa()app.use( async (ctx, next) => {ctx.response.body = '你好,我是內(nèi)地吳彥祖' })app.listen(3333, ()=>{console.log('server is running at http://localhost:3333') })在我們的命令行敲上
node index.js就可以看到運(yùn)行結(jié)果啦:
幾個(gè)核心概念
中間件好基友ctx和next
在上面的代碼中,我們可以看到app.use后面使用了2個(gè)參數(shù),ctx和next,下面我們介紹一個(gè)這哥倆到底干嘛的
ctx
ctx作為上下文使用,Koa將 node 的 request, response 對(duì)象封裝進(jìn)一個(gè)單獨(dú)對(duì)象。即ctx.request 、 ctx.response。Koa 內(nèi)部又對(duì)一些常用的屬性或者方法做了代理操作,使得我們可以直接通過 ctx 獲取。比如,ctx.request.url 可以寫成 ctx.url。
next
next 參數(shù)的作用是將處理的控制權(quán)轉(zhuǎn)交給下一個(gè)中間件
經(jīng)典的洋蔥圖概念能很好的解釋next的執(zhí)行,請(qǐng)求從最外層進(jìn)去,又從最里層出來(lái)。我們看一個(gè)例子
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(`此次的響應(yīng)時(shí)間為:${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') })看一下運(yùn)行結(jié)果:
如果將‘222’函數(shù)的next()去掉的話,會(huì)發(fā)生什么呢?
可以看到,后面的‘333’中間件直接不執(zhí)行了。所以中間件的順序?qū)ext的執(zhí)行有很大的影響
路由 koa-router
我們常用koa-router來(lái)處理URL
安裝
npm i koa-router --save看一個(gè)例子:
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頁(yè)' })router.get('/user', async (ctx, next) => {ctx.body = '你好,我這里是user頁(yè)' })router.get('/error', async (ctx, next) => {ctx.body = '你好,我這里是error頁(yè)' })app.use(router.routes())app.listen(3333, ()=>{console.log('server is running at http://localhost:3333') })
koa-router也支持嵌套寫法,通過一個(gè)總路由裝載所有子路由,也非常的方便。看一個(gè)例子:
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頁(yè)' })// 子路由2 let twoRouter = new Router()twoRouter.get('/', async (ctx, next) => {ctx.body = '你好, 我這里是twoRouter頁(yè)' }).get('/home', async (ctx , next) => {ctx.body = '你好, 我這里是home頁(yè)' })// 裝載所有子路由 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') })看一下運(yùn)行結(jié)果:
獲取請(qǐng)求數(shù)據(jù)
koa-router提供了常見的 .get .put .post .del 接口來(lái)處理各種需求。實(shí)際開發(fā)中我們用的比較多的是get和post,我們來(lái)看看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中拿到我們想要的數(shù)據(jù)let data = ctx.request.querylet dataQueryString = ctx.request.querystringctx.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 ,可以看到運(yùn)行結(jié)果
可以看到區(qū)別,.query返回的結(jié)果是對(duì)象,而.querystring返回的是字符串,這個(gè)很好理解。(chrome插件顯示成json格式)
如果遵從 RESTful 規(guī)范,比如請(qǐng)求要以 '/user/:id'的方式發(fā)出的話,我們可以用下面的例子來(lái)獲取到想要的數(shù)據(jù)
添加代碼
router.get('/data/:id', async (ctx, next) => {// 也從ctx中拿到我們想要的數(shù)據(jù),不過使用的是params對(duì)象let data = ctx.paramsctx.body = data })瀏覽器運(yùn)行 http://localhost:3333/data/4396 看到結(jié)果
接下來(lái)我們看看post的例子
我們常用的請(qǐng)求post,它的數(shù)據(jù)是放在body當(dāng)中的。這個(gè)時(shí)候就推薦一個(gè)非常常用且好用的中間件-koa-bodyparser
首先安裝
npm i koa-bodyparser --save然后我們?cè)趧偛诺拇a里添加
router.get('/post', async (ctx, next) => {// 模擬一段提交頁(yè)面let html = ` <form action="/post/result" method="post"><p>你長(zhǎng)的最像哪位明星</p><input name="name" type="text" placeholder="請(qǐng)輸入名字:"/> <br/><p>輸入一段你知道的車牌號(hào)</p><input name="num" type="text" placeholder="請(qǐng)輸入車牌號(hào):"/><br/> <button>確定不改了哦</button></form> `ctx.body = html })router.post('/post/result', async (ctx, next) => {// 我們可以從ctx的request.body拿到提交上來(lái)的數(shù)據(jù)let {name, num} = ctx.request.bodyif (name && num) {ctx.body = `hello,你最像的明星是:${name},ch你知道的車牌號(hào)是:${num}`} else {ctx.body = '啊哦~你填寫的信息有誤'}})看一下運(yùn)行結(jié)果
cache
koa操作cookie是非常方便的,也是從上下文ctx中獲取。
- ctx.cookies.get(name, [options]) 讀取上下文請(qǐng)求中的cookie
- ctx.cookies.set(name, value, [options]) 在上下文中寫入cookie
在我們剛才的post請(qǐng)求的代碼中加入:
router.post('/post/result', async (ctx, next) => {// 我們可以從ctx的request.body拿到提交上來(lái)的數(shù)據(jù)let {name, num} = ctx.request.bodyif (name && num) {ctx.body = `hello,你最像的明星是:${name},ch你知道的車牌號(hào)是:${num}`ctx.cookies.set('xunleiCode',num,{domain: 'localhost', // 寫cookie所在的域名path: '/post/result', // 寫cookie所在的路徑maxAge: 10 * 60 * 1000, // cookie有效時(shí)長(zhǎng)expires: new Date('2018-09-17'), // cookie失效時(shí)間httpOnly: false, // 是否只用于http請(qǐng)求中獲取overwrite: false // 是否允許重寫})} else {ctx.body = '啊哦~你填寫的信息有誤'}})看一下運(yùn)行結(jié)果:
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的過期時(shí)間 maxAge in ms (default is 1 days)overwrite: true, //是否可以overwrite (默認(rèn)default true)httpOnly: true, //cookie是否只有服務(wù)器端可以訪問 httpOnly or not (default true)signed: true, //簽名默認(rèn)truerolling: false, //在每次請(qǐng)求時(shí)強(qiáng)行設(shè)置cookie,這將重置cookie過期時(shí)間(默認(rèn):false)renew: false, //(boolean) renew session when session is nearly expired, }; app.use(session(CONFIG, app));小結(jié)
在涉及到自己沒有接觸過的領(lǐng)域時(shí),我一直推崇先看看要怎么玩,等自己會(huì)玩了以后,再看看“究竟”怎么玩。我們通過上面的代碼和描述,已經(jīng)對(duì)koa及node有一個(gè)初步的印象和概念。下篇文章我們會(huì)有中間件的拆分,單元測(cè)試,記錄日志,管理規(guī)范等。讓我們共同成長(zhǎng)!
廣而告之
本文發(fā)布于薄荷前端周刊,歡迎Watch & Star ★,轉(zhuǎn)載請(qǐng)注明出處。
歡迎討論,點(diǎn)個(gè)贊再走吧 。???。 ~
總結(jié)
以上是生活随笔為你收集整理的【从前端到全栈】- koa快速入门指南的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 富交互Web应用中的撤销和前进
- 下一篇: 使用FastHttpApi构建多人Web