这是我第一个 koa 项目,第一次接触 koa, 基本靠百度解决问题,完全从零开始,也不知道会做到哪一步
1. mkdir koa-server
2.cd koa-server
3. npm init -y
4. npm install koa --save
5. 新建一个 app.js
const Koa = require('koa')
const app = new Koa()
app.use(async (ctx, next) => {
ctx.body = 'hello Koa'
})
app.listen(3000)
localhost:3000
到此,最最基本的就搭好了
6. npm install koa-router --save
app.js
const Koa = require('koa')
const Router = require('koa-router')
const app = new Koa()
const router = new Router()
app.use(async (ctx, next) => {
ctx.body = 'hello Koa'
await next()
})
router.get('/test', async (ctx) => {
ctx.body = 'hello koa-router'
})
app.use(router.routes()).use(router.allowedMethods())
app.listen(3000)
访问 localhost:3000/test 就可以看到 hello koa-router
7.项目不可能所有的接口都放在主文件里面,所以在 routes 新建两个文件夹 user, news,里面新建两个文件 user/admin.js , news/list.js
app.js
const Koa = require('koa')
const Router = require('koa-router')
// 引入两个文件
var admin = require('./routes/user/admin.js')
var newList = require('./routes/news/list.js')
const app = new Koa()
const router = new Router()
router.get('/', (ctx) => {
ctx.body = 'home page'
})
// 配置这两个,当你访问 /admin 这个路由是,会转发的 admin.js 文件下
router.use('/admin', admin.routes())
router.use('/news', newList.routes())
app.use(router.routes()).use(router.allowedMethods())
app.listen(3000)
routes/user/admin.js
const router = require('koa-router')()
router.get('/user', (ctx) => {
ctx.body = 'admin'
})
module.exports = router
localhost:300/admin/user
这是最简单的 get 请求
有的时候我们需要动态匹配路由
const router = require('koa-router')()
router.get('/user', (ctx) => {
ctx.body = 'admin'
})
router.get('/add/:id/:bid', async (ctx) => {
console.log(ctx.params)
// { id: '112', bid: 'qwe' }
ctx.body = '添加详情'
})
module.exports = router
localhost:3000/add/112/qwe
get 请求之后,就是 post 请求 npm install koa-bodyparser --save
app.js
const Koa = require('koa')
const Router = require('koa-router')
// 引入
var bodyParser = require('koa-bodyparser')
var admin = require('./routes/user/admin.js')
var newList = require('./routes/news/list.js')
const app = new Koa()
const router = new Router()
// 使用
app.use(bodyParser())
router.get('/', (ctx) => {
ctx.body = 'home page'
})
router.use('/admin', admin.routes())
router.use('/news', newList.routes())
app.use(router.routes()).use(router.allowedMethods())
app.listen(3000)
routes/news/list.js
const router = require('koa-router')()
router.get('/list', (ctx) => {
ctx.body = 'list'
})
router.post('/postRoute', async (ctx, next) => {
const rb = ctx.request.body
console.log(rb);
ctx.response.body = 'success'
})
module.exports = router
post 在浏览器的地址栏里面直接输入是不可以的,可以使用 postman 来进行测试,(主要是我没有使用静态模板,毕竟都前后端分离了。)但是使用postman进行post测试要注意一点,划重点了啊
一定要记得这样选,不然你返回的就只有一个 {}
{ user: 'mjhgf', age: '111', sex: '0' }
8. 身为后台,操作数据库是最基本的了,接下来就要进行对数据库的操作了。npm install mongodb --save
根目录下新建一个 utils 文件夹 ,里面放上 config.js ,db.js
config.js
const app = {
dbUrl: 'mongodb://localhost:27017',
dbName: 'koa'
}
module.exports = app
db.js
(对MongoDB的封装)
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, { useUnifiedTopology: true }, (err, client) => {
if (err) {
reject(err)
} else {
var db = client.db(Config.dbName)
this.dbClient = db
resolve(this.dbClient)
}
})
} else {
resolve(this.dbClient)
}
})
}
find (collectionName, json) {
return new Promise((resolve, reject) => {
this.connect().then(function (db) {
var result = db.collection(collectionName).find(json)
result.toArray(function (err, docs) {
if (err) {
reject(err)
return
} else {
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(err)
return
} else {
resolve(result)
}
})
})
})
}
insert (collectionName, json) {
return new Promise((resolve, reject) => {
this.connect().then((db) => {
db.collection(collectionName).insertOne(json, function (err, result) {
if (err) {
reject(err)
return
} else {
resolve(result)
}
})
})
})
}
remove (collectionName, json) {
return new Promise((resolve, reject) => {
this.connect().then((db) => {
db.collection(collectionName).removeOne(json, function (err, result) {
if (err) {
reject(err)
return
} else {
resolve(result)
}
})
})
})
}
// 查询 _id
gteObjectID (id) {
return new ObjectID(id)
}
}
module.exports = Db.getInstance()
routes/user/admin.js
(你得提前连接自己的数据库,在数据库里面新建一个 koa 数据库 里面新建一个 user 表)
const router = require('koa-router')()
const DB = require('../../utils/db.js')
router.get('/user', async (ctx) => {
var result = await DB.find('user', {})
ctx.body = result
})
module.exports = router
这样就可以使用 koa 操作数据库了。
9.对数据库增删改查
routes/user/admin.js
const router = require('koa-router')()
const DB = require('../../utils/db.js')
router.get('/add/:id/:bid', async (ctx) => {
// http://localhost:3000/add/112/qwe
console.log(ctx.params)
// { id: '112', bid: 'qwe' }
ctx.body = '添加详情'
})
// 查询
router.get('/list', async (ctx) => {
var result = await DB.find('user', {})
ctx.body = result
})
// 插入
router.post('/doAdd', async (ctx) => {
let data = await DB.insert('user', ctx.request.body)
ctx.body = data
try {
if (data.result.ok) {
console.log(ctx.body)
}
} catch (error) {
console.log(err)
ctx.redirect('/')
}
})
// 删除
router.get('/remove', async (ctx) => {
// let user = ctx.query.user
let user = ctx.request.body.user
console.log(user)
var data = await DB.remove('user', {'user': user})
try {
if (data.result.ok) {
// ctx.redirect('/')
ctx.body = data
}
} catch (error) {
console.log(err)
}
})
// 更新
router.get('/update', async (ctx) => {
var id = ctx.query.id
var user = ctx.query.user
var age = ctx.query.age
var sex = ctx.query.sex
console.log(DB.getObjectID(id), user, age, sex)
let data = await DB.update('user', {'_id': DB.getObjectID(id)}, {
age,
sex
})
try {
if (data.result.ok) {
ctx.body = data
}
} catch (error) {
console.log(err)
ctx.redirect('/add')
}
})
module.exports = router
基本的数据库操作就到这里了。
10.登录和注册功能
新建一个 login.js
const router = require('koa-router')()
const DB = require('../../utils/db.js')
router.post('/register', async (ctx) => {
let data = await DB.insert('author', ctx.request.body)
console.log(data)
ctx.body = data
try {
if (data.result.ok) {
ctx.redirect('/login/getInfo')
}
} catch (error) {
console.log(error)
// ctx.redirect('/')
}
})
router.post('/login', async (ctx) => {
let name = ctx.request.body.name
let email = ctx.request.body.email
let pwd = ctx.request.body.pwd
console.log(name, email, pwd)
var result = await DB.find('author',
{'name': name, 'email': email, 'pwd': pwd})
console.log(result)
try {
if (result.length > 0) {
ctx.body = '登录成功'
ctx.redirect('/')
}
} catch (error) {
console.log(error)
// ctx.redirect('/')
}
})
router.get('/getInfo', async (ctx) => {
var result = await DB.find('author', {})
ctx.body = result
})
module.exports = router
11. 利用 JWT 设置 Token
const Koa = require('koa')
const Router = require('koa-router')
const bodyParser = require('koa-bodyparser')
const jwt = require('jsonwebtoken')
const jwtKoa = require('koa-jwt')
var admin = require('./routes/user/admin.js')
var newList = require('./routes/news/list.js')
var login = require('./routes/user/login.js')
const DB = require('./utils/db.js')
const keys = require('./utils/config')
const app = new Koa()
const router = new Router()
const secret = 'secret'
app.use(jwtKoa({secret}).unless({
path: [/\/register/, /\/login/]
}))
app.use(bodyParser())
app.use(async (ctx, next) => {
console.log(ctx)
let params =Object.assign({}, ctx.request.query, ctx.request.body);
ctx.request.header = {'authorization': "Bearer " + (params.token || '')}
await next();
})
router.get('/', async (ctx) => {
ctx.body = 'home'
})
router.post('/register', async (ctx) => {
console.log(ctx.request.body.email)
let email = ctx.request.body.email
const findResult = await DB.find('author', {
'email': email
})
console.log(findResult)
if (findResult.length > 0) {
ctx.status = 506
ctx.body = { email: '邮箱已被占用 ' }
} else {
let data = await DB.insert('author', ctx.request.body)
console.log(data)
ctx.body = data
try {
if (data.result.ok) {
ctx.body = {
mssage: '注册成功'
}
}
} catch (error) {
console.log(error)
// ctx.redirect('/')
}
}
})
router.post('/login', async (ctx, next) => {
let name = ctx.request.body.name
let email = ctx.request.body.email
let pwd = ctx.request.body.pwd
console.log(name, email, pwd)
var result = await DB.find('author',
{'name': name, 'email': email})
console.log(result)
if (result.length === 0) {
ctx.status = 404
ctx.body = { email: '用户不存在!' }
} else {
var result = await DB.find('author',{'pwd': pwd})
if (result) {
// 返回token
const payload = { pwd: pwd, name: name}
const token = jwt.sign(payload, keys.secretOrkey, { expiresIn: 3600 })
ctx.status = 200
ctx.body = { success: true, token: 'Bearer ' + token }
} else {
ctx.status = 400
ctx.body = { password: '密码错误!' }
}
}
})
router.use('/admin', admin.routes())
router.use('/news', newList.routes())
router.use('/login', login.routes())
app.use(router.routes()).use(router.allowedMethods())
app.listen(3000)