npm i -g koa-generator
Koa2 koa2-test # 初始化项目
const router = require('koa-router')()
router.prefix('/api')
router.get('/', async (ctx, next) => {
await ctx.render('index', {
title: 'Hello Koa 2!'
})
})
router.get('/string', async (ctx, next) => {
ctx.body = 'koa2 string'
})
router.get('/json', async (ctx, next) => {
ctx.body = {
title: 'koa2 json'
}
})
module.exports = router
app.use(index.routes(), index.allowedMethods());
ctx 可以看做req、和res的集合体
router.get('/bar', function (ctx, next) {
ctx.request.body;//请求参数体
ctx.query;//请求参数
ctx.session;//获取session
ctx.cookie;
ctx.cookies.get(name, [options]);
ctx.cookies.set(name, value, [options]);
ctx.body={};//返回参数体
})
// logger
// 记录下面几个路由用的时间
app.use(async (ctx, next) => {
const start = new Date()
await next()
const ms = new Date() - start
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`)
})
// routes
app.use(index.routes(), index.allowedMethods());
app.use(users.routes(), users.allowedMethods());
app.use(user.routes(), user.allowedMethods());
app.use(blog.routes(), blog.allowedMethods());
yarn add koa-generic-session koa-redis redis
app.js
//session
const session = require('koa-generic-session');
const redisStore = require('koa-redis');
const {REDIS_CONF} = require('./conf/db');
//session配置 在注册路由之前写
app.keys = ['DSDSDsds890809'];
app.use(session({
//配置cookie
cookie: {
path: '/',
httpOnly: true,
maxAge: 24 * 60 * 60 * 1000
},
//配置redis
store: redisStore({
all: `${REDIS_CONF.host}:${REDIS_CONF.port}`
})
}));
测试:
router.get('/session-test', async function (ctx, next) {
let session = ctx.session;
if (session.vievCount == null) {
session.vievCount = 0;
}
session.vievCount++;
ctx.body = session.vievCount
});
redis.js
const redis = require('redis')
const {REDIS_CONF} = require('../conf/db')
//创建客户端
let redisClient = redis.createClient(REDIS_CONF.port, REDIS_CONF.host);
redisClient.on('error', err => {
console.log(err)
});
module.exports = redisClient
app.js
let RedisStore = require('connect-redis')(session);
let redisClient = require('./db/redis');
let sessionStore = new RedisStore({
client: redisClient
});
app.use(session({
secret: 'asdXXnkj_asdnsk_90789_sad',
cookie: {
path: '/',//默认
httpPnly: true,//默认
maxAge: 24 * 60 * 60 * 1000
},
store: sessionStore
})); // 处理session
loginCheck.js
const {SuccessModel, ErrorModel} = require('../model/resModel');
module.exports = (re, res, next) => {
if (require.session.username) {
next()
} else {
res.json(new ErrorModel("未登录"))
}
}
路由里面:
blog.js
const loginCheck = require('../middleware/loginCheck')
router.post('/new', loginCheck, (req, res, next) => {
req.body.author = req.session.username
const result = newBlog(req.body)
return result.then(data => {
res.json(
new SuccessModel(data)
)
})
})
yarn add koa-morgan
app.js
//日志
const path = require('path');
const fs = require('fs');
const morgan = require('koa-morgan');
//日志记录
const ENV = process.env.NODE_ENV
if (ENV !== 'production') {
// 开发环境 / 测试环境
app.use(morgan('dev'));
} else {
// 线上环境
const logFileName = path.join(__dirname, 'logs', 'access.log')
const writeStream = fs.createWriteStream(logFileName, {
flags: 'a'
})
app.use(morgan('combined', {
stream: writeStream
}));
}
const Koa = require('koa')
const app = new Koa()
const views = require('koa-views')
const json = require('koa-json')
const onerror = require('koa-onerror')
const bodyparser = require('koa-bodyparser')
const logger = require('koa-logger');
//session
const session = require('koa-generic-session');
const redisStore = require('koa-redis');
const {REDIS_CONF} = require('./conf/db');
//路由
const index = require('./routes/index')
const users = require('./routes/users')
const user = require('./routes/my/user')
const blog = require('./routes/my/blog')
//日志
const path = require('path');
const fs = require('fs');
const morgan = require('koa-morgan');
// error handler
onerror(app)
// middlewares
app.use(bodyparser({
enableTypes: ['json', 'form', 'text']
}))
app.use(json())
app.use(logger())
app.use(require('koa-static')(__dirname + '/public'))
app.use(views(__dirname + '/views', {
extension: 'pug'
}))
// logger
app.use(async (ctx, next) => {
await next();
let rt = ctx.response.get('X-Response-Time');
console.log(`${ctx.method} ${ctx.url} - ${rt}`)
})
app.use(async (ctx, next) => {
const start = new Date();
await next();
const ms = new Date() - start;
ctx.set('X-Response-Time', `${ms}ms`)
})
//日志记录
const ENV = process.env.NODE_ENV
if (ENV !== 'production') {
// 开发环境 / 测试环境
app.use(morgan('dev'));
} else {
// 线上环境
const logFileName = path.join(__dirname, 'logs', 'access.log')
const writeStream = fs.createWriteStream(logFileName, {
flags: 'a'
})
app.use(morgan('combined', {
stream: writeStream
}));
}
//session配置
app.keys = ['DSDSDsds890809'];
app.use(session({
//配置cookie
cookie: {
path: '/',
httpOnly: true,
maxAge: 24 * 60 * 60 * 1000
},
//配置redis
store: redisStore({
all: `${REDIS_CONF.host}:${REDIS_CONF.port}`
})
}));
// routes
app.use(index.routes(), index.allowedMethods());
app.use(users.routes(), users.allowedMethods());
app.use(user.routes(), user.allowedMethods());
app.use(blog.routes(), blog.allowedMethods());
// error-handling
app.on('error', (err, ctx) => {
console.error('server error', err, ctx)
});
module.exports = app
const http = require('http');
//组合中间件
function compose(middlewareList) {
return function (ctx) {
//中间件调用
function dispatch(i) {
let fn = middlewareList[i]
try {
return Promise.resolve(fn(ctx, dispatch.bind(null, i + 1)))
} catch (e) {
return Promise.reject(e)
}
}
return dispatch(0);
}
}
class LikeKoa2 {
constructor() {
//中间件
this.middlewareList = []
}
use(fn) {
this.middlewareList.push(fn)
return this
}
listen(...args) {
let server = http.createServer(this.callback());
server.listen(...args)
}
createCtx(req, res) {
let ctx = {req, res};
ctx.query = req.query;
return ctx
}
handleRequest(ctx, fn) {
return fn(ctx);
}
callback() {
let fn = compose(this.middlewareList);
return (req, res) => {
let ctx = this.createCtx(req, res);
return this.handleRequest(ctx, fn)
};
}
}
module.exports = () => {
return new LikeKoa2();
}
测试:
const Koa = require('./likeKoa2');
const app = Koa();
// logger
app.use(async (ctx, next) => {
await next();
const rt = ctx['X-Response-Time'];
console.log(`${ctx.req.method} ${ctx.req.url} - ${rt}`);
});
// x-response-time
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
ctx['X-Response-Time'] = `${ms}ms`;
});
// response
app.use(async ctx => {
ctx.res.end('This is like koa2');
});
app.listen(8000);