@2890594972
2018-04-21T02:59:25.000000Z
字数 8862
阅读 1198
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 而言,即使是父类也会返回trueconst 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 = 302ctx.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信息的mysqllet 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 + 1ctx.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())
#
#