Koa 是 Node.js 的框架之一,使用洋葱模型,是一个轻量级的服务端应用。
KOA 一些 API 的使用
设置响应头
ctx.set('Allow', 'GET,POST')
|
批量注册路由 routes
const fs = require('fs')
module.exports = (app) => { fs.readdirSync(__dirname).forEach(file => { if (file === 'index.js') { return } const route = require(`./${file}`) app.use(route.routes()).use(route.allowedMethods()) }) } ----------- 分割线 ------------
const Koa = require('koa') const body = require('koa-body') const app = new Koa() const routing = require('./routes') routing(app) app.use(body({ multipart: true, formidable: { uploadDir: path.join(__dirname, '/public/uploads'), keepExtensions: true } }))
app.listen(3000, () => console.log('程序启动成功在3000端口'))
|
控制器的处理封装 controllers
class HaomeCtl { index(ctx) { ctx.body = '这是首页' } } module.exports = new HaomeCtl()
const Router = require('koa-router') const router = new Router()
const { index } = require('../controllers/home') router.get('/', index) module.exports = router
|
错误处理中间件 koa-json-error
npm install koa-json-error --save
const error = require('koa-json-error') app.use( error({ postFormat: (e, { stack, ...rest }) => process.env.NODE_ENV === 'production' ? rest : { stack, ...rest }, }) )
|
windows 系统跨平台设置环境变量
npm install cross-env --save-dev
开发环境使用
"scripts": { "start": "cross-env NODE_ENV=production node app", "dev": "nodemon app" },
|
koa-jwt 中间件
npm i koa-jwt --save
const jwt = require('koa-jwt')
const auth = jwt({ secret })
|
上传文件 使用 koa-body
app.use( body({ multipart: true, formidable: { uploadDir: path.join(__dirname, '/public/uploads'), keepExtensions: true, }, }) )
class HaomeCtl { index(ctx) { ctx.body = '这是首页' } upload(ctx) { const file = ctx.request.files.file ctx.body = { path: file.path } } }
module.exports = new HaomeCtl()
const Router = require('koa-router') const router = new Router()
const { index, upload } = require('../controllers/home')
router.get('/', index).get('/upload', upload)
module.exports = router
|
使用 koa-static 中间件生成图片链接
npm i koa-static --save
const koaStatic = require('koa-static') app.use( koaStatic( path.join(__dirname, 'public') ) )
const path = require('path')
class HaomeCtl { index(ctx) { ctx.body = '这是首页' } upload(ctx) { const file = ctx.request.files.file const basename = path.basename(file.path) ctx.body = { url: `${ctx.origin}/uploads${basename}` } } }
module.exports = new HaomeCtl()
|
Koa 的使用
初用 koa
npm install koa --save
const Koa = require('koa')
const app = new Koa()
app.use(async (ctx) => { ctx.body = '哈哈 你好 koa2 我来学习你了' })
app.listen(3001)
|
koa-router
.prefix(prefix) => Router const usersRouter = new Router().prefix('/users')
|
npm install koa-router --save
const Router = require('koa-router')
const router = require('koa-router')() ===> 上面更精简 或者 const Router = require('koa-router') const router = new Router()
app.use(router.routes()) app.use(router.allowedMethods)
router.get('/',(ctx,next)=>{ cty.body = 'hello koa' })
|
栗:
const Koa = require('koa')
var router = require('koa-router')()
const app = new Koa()
app.use(router.routes()).use(router.allowedMethods)
router .get('/', async (ctx) => { ctx.body = '首页' }) .get('/news', async (ctx) => { ctx.body = '新闻页面' }) .get('/newscontent', async (ctx) => { ctx.body = '新闻详情' })
app.listen(3001)
|
koa 中间件
app.use(async (ctx, next) => { await next() })
|
.get('/newscontent', async (ctx,next) => { console.log('新闻详情') await next() }) .get('/newscontent',async(ctx, next)=>{ ctx.body = '新闻详情' })
|
app.use(async (ctx, next) => { console.log('这是一个中间件') next() if (ctx.status == 404) { ctx.status = 404 ctx.body = '这是一个404页面' } else { console.log(ctx.url) } })
|
ctx.state = { } ----- 实例 ----- app.use(async (ctx) => { ctx.state.useinfo = '张三' next() })
|
koa 中的 ejs 模板引擎
npm install koa-views --save && npm install ejs --save
const views = require('koa-views')
app.use(views('views', { map: { html: 'ejs' } }))
app.use(views('views', { extension: 'ejs' }))
await ctx.render('index')
|
栗:
router .get('/', async (ctx) => {
let title = '我是要传入 ejs 文件中的数据' let arr = [111, 222, 333] await ctx.render('index', { title, arr }) })
<body> <h2>这是一个 ejs 的模板引擎</h2> <h3><%=title%></h3> <ul> <%for (var i = 0; i<arr.length; i++){%> // 循环 ejs 数据 <li><%=arr[i]%></li> <%}%> </ul> </body>
<% include public/header.ejs%>
<%-content%>
|
koa 中 处理 post 的 koa-bodyparser 中间件
npm install koa-bodyparser --save
const bodyParser = require('koa-bodyparser')
app.use(bodyParser())
router.post('/doAdd', async (ctx) => { ctx.body = ctx.request.body })
|
koa-static 静态资源中间件
npm install koa-static –save
const static = require('koa-static')
app.use(static(__dirname+'/public'))
------------ 分割线 ------------
router.use(async (ctx) => { ctx.state.__HOST__ = 'http://' + ctx.request.header.host })
<link rel="stylesheet" href="{{__HOST__}}/admin/css/font-aw.min.css" />
|
art-template 模板引擎
npm install art-template --save && npm install koa-art-template --save
const render = require('koa-art-template')
render(app, { root: path.join(__dirname, 'views'), extname: '.html', debug: process.env.NODE_ENV !== 'production', })
await ctx.render('user')
|
栗:
{{include 'public/footer.html'}} {{obj.name}} {{@obj.h}} {{if num >20}} 大于 20 {{else}} 小于等于 20 {{/if}} // 条件判断 <ul> // each 循环 {{each obj.arr}} <li>{{$index}} ---- {{$value}}</li> {{/each}} </ul>
router .get('/', async (ctx) => { let obj = { name: '张三', h: '<h1>我是一个h1</h1>', num: 20, arr: [111,222,333] } await ctx.render('index', { obj })
|
koa 中 cookie 的使用
- 保存用户信息
- 浏览器历史记录
- 猜你喜欢的功能
- 10 天免登陆
- 多个页面之间的数据传递
cookie 参数:
maxAage expires path domain secure httpOnly overwrite
|
koa 中设置 和获取 cookie 的值:
ctx.cookies.set(name.value,[options])
ctx.cookies.get('name')
设置的时候先把先将它转成 ‘ base64 ’ 编码来存储 new Buffer(value).toString('base64') 使用的时候再转换回来 new Buffer(value,'base64').toString()
|
koa 中的 session
session 的工作流程:
当浏览器访问服务器并发送第一个请求时,服务器会创建一个 session 对象,生成一个类似于 key,value 的键值对,然后将 key(cookie)返回到浏览器(客户端),浏览器下次再访问时,携带 key(cookie),找到对应的 session(value),客户的信息保存在 session 中。
koa-session 的使用:
npm install koa-session --sava
const session = require('koa-session')
app.keys = ['some secret hurr']
const CONFIG = { key: 'koa:sess', maxAge: 86400000, overwrite: true, httpOnly: true, signed: true, rolling: false, renew: false, }
app.use(session(CONFIG, app))
ctx.session.username = '张三'
console.log(ctx.session.userinfo)
|
栗:
🔔 注意:使用路由一定把启动路由放在下面 否则拿不到 session
的数据。
router .get('/', async (ctx) => { console.log(ctx.session.userinfo) ctx.body = '首页' + ctx.session.userinfo }) .get('/news', async (ctx) => { console.log(ctx.session.userinfo) ctx.body = `登录成功` }) .get('/login', async (ctx) => { ctx.session.userinfo = '张三' ctx.body = `登录成功` })
router.post('/doAdd', async (ctx) => { ctx.body = ctx.request.body })
app.use(router.routes()).use(router.allowedMethods)
|
MongoDB 的封装及使用
ES6 的简单封装单例模式。
class Db { static getInstance() { if (!Db.instance) { Db.instance = new Db() } return Db.instance }
constructor() { console.log('实例化触发构造函数') this.connect() }
connect() { console.log('链接数据库') }
find() { console.log('查询数据库') } }
let myDb = Db.getInstance()
|
安装以及简单使用:
npm install mongodb --save-dev
const MongoClient = require('mongodb').MongoClient
const dbUrl = 'mongodb://localhost:27017/' const dbName = 'demo'
console.time('start') MongoClient.connect(dbUrl, { useNewUrlParser: true }, (err, client) => { if (err) { console.log(err) return } let db = client.db(dbName) db.collection('user').insertOne( { username: '王武', age: 32, sex: '男', status: '1', }, (err, result) => { if (!err) { console.log('增加数据成功') client.close() console.timeEnd('start') } } ) })
let result = db.collection('user').find({}) result.toArray((err, docs) => { console.log(docs) })
|
提高性能,单例封装:
const app = { dbUrl: 'mongodb://localhost:27017', dbName: 'demo' }
module.exports = app; ------------ 分割 ---------
const MongoClient = require('mongodb').MongoClient; const ObjectID = require('mongodb').ObjectID; const Config = require('./config.js');
class Db {
static getInstance() { if (!Db.instance) { Db.instance = new Db(); } return Db.instance; }
constructor() { this.dbClient = ''; this.connect()
}
connect() { return new Promise((resolve, reject) => { if (!this.dbClient) { MongoClient.connect(Config.dbUrl, { useNewUrlParser: true }, (err, client) => { if (err) { reject('链接数据库失败'); } else { let db = client.db(Config.dbName); this.dbClient = db; resolve(db); } }) } else { resolve(this.dbClient) } }) }
find(collectionName, json) { return new Promise((resolve, reject) => { this.connect().then((db) => { let result = db.collection(collectionName).find(json); result.toArray((err, docs) => { if (err) { reject('数据找不到对应的集合(表),请检查') } resolve(docs) })
}) }) } update(collectionName, json1, json2) { return new Promise((resolve, reject) => { this.connect().then((db) => { db.collection(collectionName).updateOne(json1, { $set: json2 }, (err, result) => { if (err) { reject('更新数据失败'); } else { resolve(result) } }) }) }) } insert(collectionName, json) { return new Promise((resolve, reject) => { this.connect().then((db) => { db.collection(collectionName).insertOne(json, (err, result) => { if (err) { reject('添加数据失败') } else { resolve(result) } }) }) }) }
remove(collectionName, json) { return new Promise((resolve, reject) => { this.connect().then((db) => { db.collection(collectionName).removeOne(json, (err, result) => { if (err) { reject('删除数据失败') } else { resolve(result) } }) }) }) } getObjectId(id){ return new ObjectID(id) } }
module.exports = Db.getInstance();
|
简单的使用:
.get('/add', async (ctx) => { let data = await DB.insert('user', { username: '赵六', age: 26, sex: '女', status: '1' }) console.log(data.result); }) .get('/edit', async (ctx) => { let data = await DB.update('user',{ username: '张三的小弟' },{ username: '我是祁连山,不是张三他小弟' }) console.log(data.result); }) .get('/delete', async (ctx) => { let data = await DB.remove('user',{ username: '张三' }) console.log(data.result); })
|
小技巧:
ctx.redirect('/');
<td><a href="/edit?id={{@$value._id}}">编辑</a>
const ObjectID = require('mongodb').ObjectID;
|
验证码模块 svgCaptcha
npm install --save svg-captcha
const svgCaptcha = require('svg-captcha');
const captcha = svgCaptcha.create( { size: 4, fontSize: 50, width: 120, height: 34, background: "#cc9966" });
ctx.session.code = captcha.text; ctx.response.type = 'image/svg+xml'; ctx.body = captcha.data;
<meta http-equiv="refresh" content="5; url='http://www.qq.com/'">
|
利用 koa-jsonp 写 api 接口
npm install koa-jsonp --save
const jsonp = require('koa-jsonp')
app.use(jsonp())
|