NodeJS框架Express与Koa对比 框架介绍 express框架是一个基于 Node.js 平台的极简、灵活的 web 应用开发框架,主要基于 Connect 中间件,并且自身封装了路由、视图处理等功能。
koa是 Express 原班人马基于 ES6 新特性重新开发的框架,主要基于 co 中间件,框架自身不包含任何中间件,很多功能需要借助第三方中间件解决,但是由于其基于 ES6 generator 特性的异步流程控制,解决了 “callback hell” 和麻烦的错误处理问题。
相同点 两个框架都对http进行了封装。相关的api都差不多,同一批人所写。
不同点 express内置了许多中间件可供使用,而koa没有。
express包含路由,视图渲染等特性,而koa只有http模块。
express的中间件模型为线型,而koa的中间件模型为U型,也可称为洋葱模型构造中间件。
express通过回调实现异步函数,在多个回调、多个中间件中写起来容易逻辑混乱。
一、起步:创建一个简单的服务器 原生node
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var http = require ('http' );http.createServer (function (request, response ) { response.writeHead (200 , {'Content-Type' : 'text/plain' }); response.end ('Hello World\n' ); }).listen (8888 ); console .log ('Server running at http://127.0.0.1:8888/' );const app=http.createServer ()app.on ('request' ,(req,res )=> {})
express
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 var express = require ('express' );var app = express (); app.get ('/' , function (req, res ) { res.send ('Hello World' ); }) var server = app.listen (8081 , function ( ) { var host = server.address ().address var port = server.address ().port console .log ("应用实例,访问地址为 http://%s:%s" , host, port) })
koa
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const Koa = require ('koa' );const app = new Koa ();app.use (async (ctx, next) => { await next (); ctx.response .type = 'text/html' ; ctx.response .body = '<h1>Hello, koa2!</h1>' ; }); app.listen (3000 ); console .log ('app started at port 3000...' );
二、请求和响应 express
1 2 3 app.get ('/' , function (req, res ) { })
koa 参数ctx是由koa传入的封装了request和response的变量,我们可以通过它访问request和response,next是koa传入的将要处理的下一个异步函数。
1 2 3 4 5 6 7 async (ctx, next) => { await next (); ctx.response .type = 'text/html' ; ctx.response .body = '<h1>Hello, koa2!</h1>' ; }
三、路由 原生node
1 2 3 4 var server = require ("./server" );var router = require ("./router" ); server.use (router.route );
express
1 2 3 4 5 6 7 8 9 10 app.get ('/' , function (req, res ) { console .log ("主页 GET 请求" ); res.send ('Hello GET' ); }) app.post ('/' , function (req, res ) { console .log ("主页 POST 请求" ); res.send ('Hello POST' ); })
koa
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 app.use (async (ctx, next) => { if (ctx.request .path === '/' ) { ctx.response .body = 'index page' ; } else { await next (); } }); const Koa = require ('koa' );const router = require ('koa-router' )();const app = new Koa ();router.get ('/hello/:name' , async (ctx, next) => { var name = ctx.params .name ; ctx.response .body = `<h1>Hello, ${name} !</h1>` ; }); router.get ('/' , async (ctx, next) => { ctx.response .body = '<h1>Index</h1>' ; }); app.use (router.routes ()); app.listen (3000 ); console .log ('app started at port 3000...' );
四、静态文件 express
1 2 app.use ('/public' , express.static ('public' ));
koa
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 let staticFiles = require ('./static-files' );app.use (staticFiles ('/static/' , __dirname + '/static' )); const Koa = require ('koa' );const app = new Koa ();const bodyParser = require ('koa-bodyparser' );const Router = require ('koa-router' );const router = new Router ();const render = require ('koa-ejs' );const path = require ('path' );const serve = require ('koa-static' );app.use (bodyParser ()); app.use (serve (path.join (__dirname + "/public" ))); render (app, { root : path.join (__dirname, 'views' ), layout : false , viewExt : 'html' , cache : false , debug : false }); app.listen (3000 );
五、get\post传参接收方法 原生node
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 var http = require ('http' );var url = require ('url' );var util = require ('util' ); http.createServer (function (req, res ){ res.writeHead (200 , {'Content-Type' : 'text/plain' }); var params = url.parse (req.url , true ).query ; res.write ("网站名:" + params.name ); res.write ("\n" ); res.write ("网站 URL:" + params.url ); res.end (); }).listen (3000 ); var http = require ('http' );var querystring = require ('querystring' );http.createServer (function (req, res ) { var body = "" ; req.on ('data' , function (chunk ) { body += chunk; }); req.on ('end' , function ( ) { body = querystring.parse (body); res.writeHead (200 , {'Content-Type' : 'text/html; charset=utf8' }); if (body.name && body.url ) { res.write ("网站名:" + body.name ); res.write ("<br>" ); res.write ("网站 URL:" + body.url ); } else { res.write (postHTML); } res.end (); }); }).listen (3000 );
express get 传参接收方法
1 2 3 4 5 6 7 8 9 10 app.get ('/process_get' , function (req, res ) { var response = { "first_name" :req.query .first_name , "last_name" :req.query .last_name }; console .log (response); res.end (JSON .stringify (response)); })
post传参接收方法
1 2 3 4 5 6 7 8 9 10 app.post ('/process_post' , urlencodedParser, function (req, res ) { var response = { "first_name" :req.body .first_name , "last_name" :req.body .last_name }; console .log (response); res.end (JSON .stringify (response)); })
koa
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const bodyParser = require ('koa-bodyparser' );router.post ('/signin' , async (ctx, next) => { var name = ctx.request .body .name || '' , password = ctx.request .body .password || '' ; console .log (`signin with name: ${name} , password: ${password} ` ); if (name === 'koa' && password === '12345' ) { ctx.response .body = `<h1>Welcome, ${name} !</h1>` ; } else { ctx.response .body = `<h1>Login failed!</h1> <p><a href="/">Try again</a></p>` ; } }); app.use (bodyParser ());
六、cookie管理 express 使用中间件向 Node.js 服务器发送 cookie 信息
1 2 3 4 5 6 7 8 9 10 11 12 13 var express = require ('express' )var cookieParser = require ('cookie-parser' )var util = require ('util' ); var app = express ()app.use (cookieParser ()) app.get ('/' , function (req, res ) { console .log ("Cookies: " + util.inspect (req.cookies )); }) app.listen (8081 )