当前位置: 首页 > 后端技术 > Node.js

Express实用技巧与设计模式

时间:2023-04-03 23:42:23 Node.js

Express实用技巧与设计模式1.Express简介Express是一个简洁灵活的node.jsweb应用开发框架。它是目前最流行的基于node.js的Web开发框架。它提供了一系列强大的功能,例如:路由控制中间件静态文件服务模板解析本文主要介绍这些功能的使用及其设计理念里面是一个应用返回的handle函数,所有express方法都是app上的原型方法)我们可以调用express方法varexpress=require('express)varapp=express()app.liten(3000)3.路由控制express通过匹配请求路径进行请求和响应操作。有关详细信息,请参见下面的get和post方法。Express的get方法第一个参数path为请求路径,第二个参数为回调函数app.get(path,function(req,res))get方法usesconstexpress=require('express');constapp=express();//匹配http://localhost:3000/hello做相关的req,res操作app.get('/hello',function(req,res){res.end('hello');});//匹配http://localhost:3000/world做相关的req和res操作app.get('/world',function(req,res){res.end('world');});//全部匹配,主要用作未找到app.get('*',function(req,res){res.setHeader('Content-Type','text/plain;charset=utf8');res.end('NotFound');});app.listen(3000);Express的post方法第一个参数path为请求路径,第一个第二个参数为处理请求的回调函数,与getapp相同.post(path,function(req,res))post方法使用varexpress=require('./express');varapp=express();//匹配http://localhost:3000/hello做相关的req,res操作app.post('/hello',function(req,res){res.end('hello');});//全部匹配,主要用于未找到app.post('*',function(req,res){res.end('postnotfound');});app.listen(3000);通过linux命令发送post请求$curl-XPOSThttp://localhost:3000/helloExpress的all方法监听所有请求方法可以匹配所有HTTP动词根据请求路径处理来自客户端的所有请求,参数同上constapp=express();('/world',function(req,res){res.end('allworld');});app.listen(3000);ExpressRouter的设计理念先看下面代码constexpress=require('express');constapp=express();app.get('/user',function(req,res,next){console.log(1);next();},function(req,res,next){console.log(11);next();}).get('/world',function(req,res,next){console.log(2);next();}).get('/你好',function(req,res,next){console.log(3);res.end('ok');});app.listen(3000);上面的代码体现了一个expressrouter的概念,它是一个二维数组二维数据形式,这个概念的主要意思是:在router路由容器中存放一层路由实例,并存放一层回调在每一层路由实例中,当匹配到上一个路由时,执行其中的回调如下图,路由和路由分别入栈。不同的是Router中的stack存放的是Route,根据相同的路由匹配,遍历Stack中的相关Routes,handle方法是挂载在层上的Route。并触发Route遍历Route中的Stack。Route中的Stack层层存放回调,所以所有的回调最终都是在同一个匹配路径上调用的。核心原理就是这个二维数组4的二维数据形式。是否登录,检查用户是否有访问权限等。它的特点是:一个中间件在处理完请求和响应后,可以将相应的数据传递给下一个中间件的回调函数的next参数,表示接受来自其他中间件的调用,函数体中的next()表示将请求数据传递下去,可以根据返回的路径区分执行不同的中间件1.中间件的使用主要是通过use方法var快递=要求('快递');varapp=express();app.use(function(req,res,next){console.log('matchall');next();});app.use('/water',function(req,res,next){console.log('Onlymatch/water');next();});app.get('/water',function(req,res){res.end('water');});app.listen(3000);2、中间件的原理是通过Application原型上的use方法改变Router的功能,抽象出Router的方法进行复用,由Router处理中间件,其实就是上面说的路由控制原理。下面的use方法调用中间件,你也可以创建一个express.router,在app下通过use调用这个中间件,形成父子级的中间件路由。下面的user.use是访问/user/或/user/2个子路由时constexpress=require('../');constapp=express();app.use(function(req,res,next){console.log('Ware1:',Date.now());next('wrong');});app.get('/',function(req,res,next){res.end('1');});constuser=express.Router();user.use(function(req,res,next){console.log('Ware2',Date.now());next();});user.use('/2',function(req,res,next){res.end('2');});app.use('/user',user);app.use(function(err,req,res,next){res.end('catch'+err);});app.listen(3000,function(){console.log('serverstartedatport3000');});3.中间件设计模式的主要思想是Application有一个router属性指向Router函数,在Router中返回一个router函数,在返回的router上挂载get/handle等方法。其实express.Router()方法就是Router函数而中间件和普通路由都在Router的栈中,如图5静态服务文件如果要在网页中加载静态文件(css、js、img),需要指定另外一个目录存放静态文件,当浏览器发送非HTML文件请求时,服务器会到该目录下查找相关文件varexpress=require('express');varapp=express();varpath=require('path');app.use(express.static(path.join(__dirname,'public')));app.listen(3000);静态文件服务器实现static属于express内置中间件,其原理主要是调用serve-static库,具体实现是一个原生的node.jsAPI,可以查看我的文章如何搭建静态服务器静态服务器6。模板分析这里主要是ejs模板。具体API请参考EJS官网安装ejs$npminstallejssettemplatevarexpress=require('express');varpath=require('path');varapp=express();app.set('viewengine','ejs');app.set('views',path.join(__dirname,'views'));app.listen(3000);渲染htmlapp.set('viewengine','html')app.set('views',path.join(__dirname,'views'));应用.engine('html',require('ejs').__express);渲染视图第一个参数是要渲染的模板第二个参数是渲染需要的数据app.get('/',function(req,res){res.render('hello',{title:'hello'},函数(错误,数据){});});模板实现res.render=function(name,data){varviewEngine=engine.viewEngineList[engine.视图类型];if(viewEngine){viewEngine(path.join(engine.viewsPath,name+'.'+engine.viewType),data,function(err,data){if(err){res.status(500).sendHeader()}.send('viewenginefailure'+err);}else{res.status(200).contentType('text/html').sendHeader().send(data);}});}else{res.status(500).sendHeader().send('查看引擎失败');}}7.结束语本文主要介绍核心功能和核心代码思想,其他方法如:redirect(重定向)、body-parser(请求体分析)、send方法等不再介绍。具体可以参考下面给出的相关教程body-parser原理及实现。ngaiwe@126.com