Node Express用法详解【安装、使用、路由、中间件、模板引擎等】
本文实例讲述了NodeExpress用法。分享给大家供大家参考,具体如下:
安装
npminstall--saveexpress
基本使用
//引用express varexpress=require('express'); //创建app varapp=express(); //罗列中间件 app.get('/',function(req,res){ res.send('index'); }); app.get('/new/:id',function(req,res){ res.send('news'+res.params.id); }); //开启服务器,监听端口 app.listen(3000);
路由
express路由
//路由小写和大写都可以。 varexpress=require('express'); varapp=express(); app.get('/',function(req,res){ res.send('get请求'); }); app.post('/',function(req,res){ res.send('post请求'); }); app.listen(1221);
get和post请求都可以
app.all('/',function(req,res){ res.send('get&post'); }); //更推荐冒号写法 app.get('/student/:id',function(req,res){}); app.get('/:username/:id',function(req,res){res.write(username);res.end(id)});
有字符串正则系统
//匹配acd和abcd app.get('/ab?cd',function(req,res){ res.send('ab?cd'); }); //匹配abcd、abbcd、abbbcd等 app.get('/ab+cd',function(req,res){ res.send('ab+cd'); }); //匹配abcd、abxcd、abRABDOMcd、ab123cd等 app.get('/ab*cd',function(req,res){ res.send('ab*cd'); }); //匹配/abe和/abcde app.get('/ab(cd)?e',function(req,res){ res.send('ab(cd)?e'); });
正则表达式
//匹配任何路径中含有a的路径: app.get(/a/,function(req,res){ res.send('/a/'); }); //路由中的正则表达式,可以使用分组捕获,程序中使用req.params[0],req.params[1]来获取 app.get(/student([\d]{1})\/class([\d]{2})$/,function(req,res){ console.log(req.params[0],req.params[1]); });
表单提交
表单提交到本身页面//restful路由设计
/* 概念: /student get//读取学生信息//app.get('/student/:id',function(){}); add//添加学生信息//app.add('/student/:id',function(){}); delete//删除学生信息//app.delete('/student/:id',function(){}); 问题:web网页中,大部分处理get和psot请求处理。 其它的服务,可以是从软件,或者app发出请求。一般restful是提供给app。 */ app.get('/',function(req,res){ res.render('form.ejs'); }); app.post('/',function(req,res){ res.send('form表单提交'); });
中间件
中间件middleware,少了一层回调。
所有的中间件,都将作为http.createServer();的回调。
中间件特点:
app.js中的代码,程序执行的时候运行,用户来了之后,并不执行。中间件中的代码块,每个用户访问的时候都会执行一次。
具有跳楼现象,从上往下走,匹配一个就执行,而不会执行第二个。
app.get('/',function(req,res){res.send('A')}); app.get('/',function(req,res){res.send('B')});//执行A,而不会执行B
中间件的回调函数中有next参数,表示继续执行下一个匹配的中间件。//利用next(),用两段小程序,来同时处理同一个请求。把业务分开。next(),影响MVC。
app.get('/',function(req,res,next){ res.send('A'); next(); }) app.get('/',function(req,res,next){ res.send('B'); }) //这两个路由,感觉没关系,实际上冲突了。 app.get('/:username/:id',function(req,res){ console.log(1); res.send('用户信息'+req.params[username]); }); app.get('/admin/login',function(req,res){ console.log(2); res.send('管理员登陆'); });
解决方法
方法1:
调整路由上下位置//利用匹配就有跳楼现象。express中所有的路由都是中间件,具体的路由往上写,抽象的往下写。
app.get('/admin/login',function(req,res){ console.log(2); res.send('管理员登陆'); }); app.get('/:username/:id',function(req,res){ console.log(1); res.send('用户信息'+req.params[username]); });
方法2:匹配到最后,要有最终的路由来匹配于它。
//加上next()之后,匹配两次,已经被send()一次,会报错。通过数据的判断适当加next() app.get('/:username/:id',function(req,res){ varusername=req.paramse.username; //检索数据库,如果username不存在,那么才next() if(usernma){ console.log(1); res.send('用户信息'+req.params[username]); }else{ next(); } }); app.get('/admin/login',function(req,res){ console.log(2); res.send('管理员登陆'); });
app.use()
此时并不会进行任何路由匹配,都是执行。一般处理404,和总体的返回编码和状态的使用。
//多个路由都能够匹配 app.use('/admin',function(req,res){ console.log(req.originUrl);//'/admin/new' console.log(req.baseUrl);//'admin' console.log(req.path);//'/new' next(); }); //任何网址都是'/'的拓展 app.use('/',function(req,res){}); app.use(function(req,res){});//可以不用第一个参数直接就是'/',就是所有网址了。 app.use();//增加一些特定功能的便利场所。 //实际上app.use();//基本上都从第三方能得到。--路由顺序(落路) app.use(user); functionuser(req,res,next){ varfilePath=req.originalUrl; fs.readFile('./public/'+filePath,function(err,data){ if(err){ //文件不存在 next() return; } res.send(data.toSting()); }); } //静态服务 app.use(express.static('./public')); //路由的上下关系,很有关系,是否匹配第一个,是否需要next() //一般习惯把静态服务写在前头,后面的路由处理,一般不冲突。 //返回编码和状态 app.use(function(req,res,next){ res.status(200); res.set('Content-Type','text/html;charset=utf-8'); next(); }); //404 app.use(function(req,res){ res.status(404); res.send('sorry'); });
render()&send()
大多数情况下,渲染内容用res.render(),将会根据views的模板文件进行渲染,如果不想使用views文件夹,使用其它名字,
app.set('views','static');
send();//自动设置了Content-Type头部和200状态码。和mime类型。send()和end()一样。
get&post
get请求的参数在url中,在原生node中,需要使用url模块来识别参数字符串,在express中,不需要使用url模块。可以直接使用req.query对象。
post请求在express中不能直接获得,必须使用body-parser模块。使用后,将可用req.body得到参数。但是如果表单中含有文件上传,那么还是需要使用formidable模块。
post使用到的第三方模块:body-parser,formidable
varexpress=require('express'); varbodyParser=require('body-parser'); varapp=express(); //设置模板 app.set('viewengine','ejs'); app.use(bodyParser.urlencoded({extended:false})); //router app.get('/',function(req,res){ res.render('form.ejs'); }); app.post('/',function(req,res){ console.log(req.body); });
静态化文件
利用expres.static(root);//root参数指的是静态资源文件所在的根目录。
//app.use方法实际上是将中间件保存在一个数组中,注册路由时,依次将数组的元素取出 app.use(express.static('./static')); app.use('page',epxress.static('./static'));//page/index.html
模板引擎
和express结合的模板是:jade,ejs
(ejs)[https://www.npmjs.com/package/ejs%5D
varexpress=require('express'); varapp=express(); //设置模板引擎,设置为ejs app.set('viewengine','ejs'); //路由 app.get('/',function(req,res){ //render:第二个参数是,字典。 res.render('index.ejs',{ 'name':[ting,daie] }); }); app.listen(1221);
对应的模板为:
-
<%
for(vari=0;i
- <%=name[i]%> <% } %>
默认的视图文件夹,views。如果不想使用默认的app.set('views','./shitu');
希望本文所述对大家node.js程序设计有所帮助。