@2890594972
2018-04-21T02:59:25.000000Z
字数 8862
阅读 1080
demo
创建项目安装依赖 mkdir koa2&&cd koa2&&npm init -y&& npm install koa --save
主页 touch app.js
const Koa = require('koa')
const app = new Koa()
app.use(ctx => {
ctx.body = `您的网址路径为:${ctx.request.url}`
})
app.listen(3000)
console.log(`koa2 已启动 , 端口 : 3000`)
启动:node app.js
-->访问 http://localhost:3000/hhhhh
依赖 npm install babel-core babel-polyfill babel-register babel-preset-env --save-dev
配置 touch .babelrc
{
"presets": ["env"]
}
touch server.js
require('babel-register');
require('babel-polyfill');
require('./app.js');
启动:node server.js
-->访问 http://localhost:3000/hhhhh
依赖 npm install nodemon -g
启动:nodemon server.js
-->访问 http://localhost:3000/hhhhh
修改package.json
"scripts": {
"start": "nodemon server.js"
}
启动:npm start
touch .gitignore
node_modules/
npm install --save koa-logger koa-convert
const koaLogger = require('koa-logger')
const convert = require('koa-convert')
app.use(convert(koaLogger()))
项目结构 mkdir controller&&touch controller/user.js controller/hello.js router.js
依赖 npm install koa-router koa-bodyparser --save
改造app.js
const Koa = require('koa')
const Router = require('koa-router')
const bodyParser = require('koa-bodyparser')
const app = new Koa()
const koaLogger = require('koa-logger')
const convert = require('koa-convert')
const router = new Router()
app.use(convert(koaLogger()))
// app.use(ctx => {
// ctx.body = `网址路径为:${ctx.request.url}`
// })
app.use(bodyParser())
router.get('/', ctx => {
ctx.body = `这是主页`
})
router.get('/user', ctx => {
ctx.body = `这是user页`
})
router.get('/post', ctx => {
ctx.body = ctx.request.body
})
router.get('/async', async ctx => {
const sleep = async (ms) => {
return new Promise(resolve => {
setTimeout(() => {
resolve(true)
}, ms)
})
}
await sleep(1000)
ctx.body = `这是异步处理页`
})
app.use(router.routes())
.use(router.allowedMethods())
app.listen(3000)
console.log(`koa2 已启动 , 端口 : 3000`)
module.exports = app;
重启应用-->访问 /, /user,/async
// index.js
const Koa = require('koa')
const app = new Koa()
const router = require('./router')
const bodyParser = require('koa-bodyparser')
app.use(bodyParser())
app.use(router.routes())
.use(router.allowedMethods())
app.listen(3000, (err) => { if (err) { console.error(err); } else { console.log(`koa2 已启动 , 端口 : 3000`); } });
// router.js
const Router = require('koa-router')
const router = new Router()
const user = require('./controller/user')
const hello = require('./controller/hello');
router.post('/user/login', user.login)
router.get('/user/profile', user.profile)
router.use('/hello', hello.routes(), hello.allowedMethods());
module.exports = router
// controller/user.js
const sleep = async (ms) => {
return new Promise(resolve => {
setTimeout(() => {
resolve(true)
}, ms)
})
}
module.exports = {
login (ctx) {
ctx.body = {
username: ctx.request.body.username
}
},
async profile (ctx) {
await sleep(1000)
ctx.body = {
username: '相学长',
sex: 'man',
age: '999'
}
}
}
controller/hello.js
var router = require('koa-router')();
//const router = Router({ prefix: '/hello'})
router.get('/', async function(ctx, next) {
ctx.state = {
title: 'abc '
};
ctx.response.body = `<h1>hello world!</h1>`;
})
router.get('/:name', async function(ctx, next) {
let name = ctx.params.name;
ctx.state = {
title: 'abc '
};
console.log(ctx.render.path);
await ctx.render('index', { hello: `abc ${name}` });
})
module.exports = router;
访问:/user/login /user/profile /hello /hello/page
router.js
const Router = require('koa-router')
const router = new Router()
const user = require('./controller/user')
// const hello = require('./controller/hello');
router.post('/user/login', user.login)
router.get('/user/profile', user.profile)
// router.use('/hello', hello.routes(), hello.allowedMethods());
const fs = require('fs');
let addControllers = (router, dir) => {
dir = dir || 'controller';
fs.readdirSync(__dirname + '/' + dir).filter((f) => {
return f.endsWith('.js');
}).forEach((f) => {
const model = require(__dirname + '/' + dir + '/' + f);
if (model.constructor == Router) {
// constructor 更加精确地指向对象所属的类,而对 instanceof 而言,即使是父类也会返回true
const modelStr = f.replace(/.js/, '');
router.use(`/${modelStr}`, model.routes(), model.allowedMethods());
}
})
}
addControllers(router);
module.exports = router
编辑中间件 mkdir middleware&&touch middleware/articles.js
module.exports = {
async edit(ctx, next) {
const locals = {
title: '编辑',
nav: 'article'
}
await ctx.render('articles/edit', locals)
},
async checkLogin(ctx, next) {
if(!ctx.state.isUserSignIn){
ctx.status = 302
ctx.redirect('/')
return
}
await next()
}
}
在路由中使用中间件
const articles = require('./middleware/articles')
router.get('/:id/edit', articles.checkLogin, articles.edit)
依赖 npm i -S ejs koa-views
app.js
const views = require('koa-views');
app.use(views(__dirname + '/views', { extension: 'html',map: { html: 'ejs' }}));
mkdir views&&touch views/index.html
<h1><%= hello %></h1>
访问 /hello/美女
npm install koa-static --save-dev
const koaStatic = require('koa-static')
const path= require("path")
app.use(koaStatic(
path.join( __dirname, './static')
))
router.get('/cookie', async function(ctx, next) {
ctx.cookies.set("demo", "demoValue", {
name: 'abc',
age: '20',
token: 'xyz'
})
console.log(ctx.cookies.get("demo"));
ctx.response.body = `cookie`;
})
npm install koa-session-minimal koa-mysql-session --save-dev
const session = require('koa-session-minimal')
const MysqlSession = require('koa-mysql-session')
// 配置存储session信息的mysql
let store = new MysqlSession({
user: 'root',
password: 'abc123',
database: 'koa_demo',
host: '127.0.0.1'
})
// 存放sessionId的cookie配置
let cookie = {
maxAge: '', // cookie有效时长
expires: '', // cookie失效时间
path: '', // 写cookie所在的路径
domain: '', // 写cookie所在的域名
httpOnly: '', // 是否只用于http请求中获取
overwrite: '', // 是否允许重写
secure: '',
sameSite: '',
signed: ''
}
// 使用session中间件
app.use(session({
key: 'SESSION_ID',
store: store,
cookie: cookie
}))
hello.js
router.get('/session', async function(ctx, next) {
// 读取session信息
ctx.session.count = ctx.session.count + 1
ctx.response.body = ctx.session;
})
router.get('/session/set', async function(ctx, next) {
ctx.session = {
user_id: Math.random().toString(36).substr(2),
count: 0
}
ctx.response.body = ctx.session;
})
npm install --save mysql
mkdir db&&touch db/mysqlUtil.js db/mysqlUser.js
mysqlUtil.js
const mysql = require('mysql')
const pool = mysql.createPool({
user: 'root',
password: 'root',
database: 'demo2',
host: '127.0.0.1'
})
let query = function(sql, values) {
return new Promise((resolve, reject) => {
pool.getConnection(function(err, connection) {
if (err) {
reject(err)
} else {
connection.query(sql, values, (err, rows) => {
if (err) {
reject(err)
} else {
resolve(rows)
}
connection.release()
})
}
})
})
}
module.exports = { query }
mysqlUser.js
const { query } = require('./mysqlUtil')
async function getUsers( ) {
let sql = 'SELECT * FROM user'
return await query( sql )
}
async function getUser( userId) {
let sql = 'select * from user where id = ?'
return await query( sql,userId )
}
module.exports = { getUsers,getUser }
controller.js
const { getUsers,getUser } = require('../db/mysqlUser')
router.get('/users', async function(ctx, next) {
return ctx.response.body = await getUsers();
})
router.get('/user/:id', async function(ctx, next) {
var id = ctx.params.id;
return ctx.response.body = await getUser(id);
})
npm install --save mongoose
touch db/mongoUtil.js
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost:27017/demo2');
mongoose.connection.on('error', function(error) {
console.log('数据库连接失败:' + error);
});
mongoose.connection.on('open', function() {
console.log('——数据库连接成功!——');
});
exports.mongoose = mongoose;
touch db/mongoEmp.js
const mongodb = require('./mongoUtil');
const Schema = mongodb.mongoose.Schema;
// schema 数据库模型骨架,不具备操作数据库能力
var dept = new Schema({
id: String, //部门编号
name: String //名称
});
var emp = new Schema({
id: Number, //工号
name: String, //姓名
age: { type: Number, default: 0 }, //年龄
// dep_id: String //部门
dep: {
type: Schema.Types.ObjectId,
ref: 'dept'
}
});
// 添加实例方法
emp.methods.printInfo = function() {
let greeting = this.name;
console.log("Testing methods defined in schema:" + greeting);
}
// 添加静态方法,在Model层就能使用
emp.statics.findbyId = function(id, callback) {
return this.model('employee').find({ id: id }, callback);
}
// model 由Schema构造生成的模型,类似于管理数据库属性、行为的类。
var employee = mongodb.mongoose.model("employee", emp);
var department = mongodb.mongoose.model('department', dept);
//Entity —— 由Model创建的实体,能影响数据库操作
var empEntity = new employee({
id: 1,
name: '姓名'
});
console.log(empEntity.name, empEntity.id);
empEntity.save(function(err, doc) {
if (err) {
console.log("error :" + err);
} else {
console.log(doc);
}
})
var empDAO = function() {};
empDAO.prototype.findAll = async function(callback) {
console.log(await employee.find({}));
return await employee.find({}, callback)
// .populate({ path: 'dep', select: { id: 1 } }).exec();
}
module.exports = new empDAO();
controller.js
const empDAO = require('../db/mongoEmp')
router.get('/emp', async function(ctx, next) {
let result = await empDAO.findAll();
await ctx.render('list', {
empList: result
})
})
touch views/list.html
<p>雇员列表</p>
<ul>
<% empList.forEach(function(item){%>
<li>
<%=item.id %>
<%=item.name %>
</li>
<% }) %>
</ul>
generator 中间件为koa1 直接使用的中间件
在koa2 使用:
const convert = require('koa-convert')
const loggerGenerator = require('./middleware/logger-generator')
app.use(convert(loggerGenerator()))
async 中间件开发
function log( ctx ) {
console.log( ctx.method, ctx.header.host + ctx.url )
}
module.exports = function () {
return async function ( ctx, next ) {
log(ctx);
await next()
}
}
async 中间件只能在 koa v2中使用
const loggerAsync = require('./middleware/logger-async')
app.use(loggerAsync())
#
#