Express和Koa2对比
获取实例
Express
var express = require('express');
// 直接从调用函数中获取
var app = express();
Koa2
const Koa = require('koa')
// 实例化后获取
const app = new Koa()
处理请求
Express
// 可以直接使用对应的请求方式判断,也可以使用应用级中间件进行处理
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.use('/', function (req, res) {
res.send('Hello World!');
});
Koa2
// 通过koa内部封装好的上下文进行判断处理
app.use( async ( ctx ) => {
if ( ctx.url === '/' && ctx.method === 'GET' ) {
// 当GET请求时候的处理
} else if ( ctx.url === '/' && ctx.method === 'POST' ) {
//post请求的处理
} else {
// 其他请求显示404
ctx.body = '<h1>404!!! o(╯□╰)o</h1>'
}
})
请求的判断和响应的设置
Express
app.get('/user/:id', function (req, res, next) {
// 在普通回调函数形参中获取请求或设置响应内容
res.send(req.params.id)
})
Koa2
app.use( async ( ctx ) => {
// 在koa封装好的上下文中获取请求
//注意:request(response)是koa封装过的内容,req(res)在ctx上下文中也能够获取的到,但是这两个对象是原生http中的请求和响应内容
let url = ctx.request.url
// 能够直接通过这种方式返回前端
ctx.body = url
})
POST请求参数的分析
Express
//在使用express构建工具时已经在根对象上挂载了中间件以处理参数
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
//如果不放心可以引入中间件body-parser
var bodyParser = require("body-parser")
// 解析 application/json
app.use(bodyParser.json());
// 解析 application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
// 在配置好中间件之后,在处理函数中直接使用req.body就能够获取post请求的参数
关于配置项的说明
extended: false;
表示使用系统模块querystring来处理,也是官方推荐的
extended: true;
表示使用第三方模块qs来处理
从功能性来讲,qs比querystring要更强大,所以这里可以根据项目的实际需求来考虑
Koa2
// 话不多说直接使用一个中间件koa-bodyparser,功能强大,能够解析post请求的参数并且挂载到ctx.request.body上
app.use(bodyParser())
app.use( async ( ctx ) => {
let data = ctx.request.body
// 能够直接通过这种方式返回前端
ctx.body = data
})
静态资源的加载
Express
- Express中存在一个内置中间件express.static
- 将静态资源文件所在的目录作为参数传递给 express.static 中间件就可以提供静态资源文件的访问了。
- 例如,假设在 public 目录放置了图片、CSS 和 JavaScript 文件,你就可以:
app.use(express.static('public'))
之后可以这样请求
http://localhost:3000/images/kitten.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost:3000/images/bg.png
http://localhost:3000/hello.html
// 注意:中间件只会在定义的目录下寻找所以无需定义pubilc目录的路径
如果你想单独加一个目录名(注意这个目录名是虚拟的实际上在你的项目结构中并不存在)你可以这样做
app.use('/static', express.static('public'))
然后你就可以这样访问了
http://localhost:3000/static/images/kitten.jpg
http://localhost:3000/static/css/style.css
http://localhost:3000/static/js/app.js
http://localhost:3000/static/images/bg.png
http://localhost:3000/static/hello.html
Koa2
//直接搞一个中间件来处理koa-static
const static = require('koa-static')
//告知静态资源目录位置后中间件会进行处理
app.use(static(
//这里需要指定
path.join( __dirname, "xxxxxx")
))
模板引擎的使用
Express(art-template)
Express框架中配置模板的过程较为繁琐
app.engine('art', require('express-art-template'))
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'art')
// routes
app.get('/', function (req, res) {
res.render('index.art', {
user: {
name: 'aui',
tags: ['art', 'template', 'nodejs']
}
})
})
Koa2(ejs)
//引入中间件
const views = require('koa-views')
// 加载模板引擎,并且声明模板文件夹所处位置
app.use(views(path.join(__dirname, 'xxxxx'), {
//声明使用的模板
extension: 'ejs'
}))
app.use( async ( ctx ) => {
let title = 'hello koa2'
// 针对后缀名为ejs的模板文件进行渲染
await ctx.render('index', {
title,
})
})
路由
Express
主要通过express中的Router来获取路由对象
var express = require('express');
var router = express.Router();
// 该路由使用的中间件
router.use(function timeLog(req, res, next) {
console.log('Time: ', Date.now());
next();
});
// 定义网站主页的路由
router.get('/', function(req, res) {
res.send('Birds home page');
});
// 定义 about 页面的路由
router.get('/about', function(req, res) {
res.send('About birds');
});
<!-- 暴露路由供外部使用 -->
module.exports = router;
Koa2(koa-router)
Koa2中的路由处理我们需要引入第三方中间件koa-router
const Koa = require('koa')
const fs = require('fs')
const app = new Koa()
const Router = require('koa-router')
// 子路由1
let home = new Router()
home.get('/', async ( ctx )=>{
let html = `
<ul>
<li><a href="/page/helloworld">/page/helloworld</a></li>
<li><a href="/page/404">/page/404</a></li>
</ul>
`
ctx.body = html
})
// 子路由2
let page = new Router()
page.get('/404', async ( ctx )=>{
ctx.body = '404 page!'
}).get('/helloworld', async ( ctx )=>{
ctx.body = 'helloworld page!'
})
// 装载所有子路由
let router = new Router()
router.use('/', home.routes(), home.allowedMethods())
router.use('/page', page.routes(), page.allowedMethods())
// 加载路由中间件
app.use(router.routes()).use(router.allowedMethods())
<!--总结:所有的子路由都需要在根路由上得以装载,根路由需要在中间件上挂载处理-->
我们发现Koa2中很多处理都是建立在第三方中间件的基础上的,这也是Koa2框架不同于Express框架的一个区别,这使得Koa建立在封装的基础上更加轻便,此外,Koa中封装了异步回调的处理,我们可以避免在进行处理时造成回调地域的情况