Node Express用法详解【安装、使用、路由、中间件、模板引擎等】


Posted in Javascript onMay 13, 2020

本文实例讲述了Node Express用法。分享给大家供大家参考,具体如下:

安装

npm install --save express

基本使用

//引用express
var express = require('express');

//创建app
var app = 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 路由

//路由小写和大写都可以。
var express = require('express');

var app = 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 ){
  
  var username = 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);
function user( req,res,next ){   
  var filePath = 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-parserformidable

var express = require('express');
var bodyParser = require('body-parser');
var app = express();

// 设置模板
app.set('view engine','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 结合的模板是:jadeejs
(ejs)[https://www.npmjs.com/package/ejs%5D

var express = require('express');
var app = express();

// 设置模板引擎,设置为ejs
app.set('view engine','ejs');

// 路由
app.get('/',function( req,res ){
  //render: 第二个参数是,字典。
  res.render('index.ejs',{
    'name': [ting,daie]
  });
});  
app.listen(1221);

对应的模板为:

<ul>
  <%
    for( var i=0; i<name.length; i++ ){
  %>
    <li><%=name[i]%></li>
  <%
    }
  %>
</ul>

默认的视图文件夹,views。如果不想使用默认的 app.set('views','./shitu');

希望本文所述对大家node.js程序设计有所帮助。

Javascript 相关文章推荐
javascript之函数直接量(function(){})()
Jun 29 Javascript
Javascript 对象的解释
Nov 24 Javascript
javascript简易缓动插件(源码打包)
Feb 16 Javascript
JS 实现图片直接下载示例代码
Jul 22 Javascript
javascript 构造函数方式定义对象
Jan 02 Javascript
js实现带按钮的上下滚动效果
May 12 Javascript
jQuery实现图片与文字描述左右滑动自动切换的方法
Jul 27 Javascript
JavaScript中split与join函数的进阶使用技巧
May 03 Javascript
jQuery+ajax实现动态添加表格tr td功能示例
Apr 23 jQuery
学前端,css与javascript重难点浅析
Jun 11 Javascript
解决vue项目获取dom元素宽高总是不准确问题
Jul 29 Javascript
基于vue 动态菜单 刷新空白问题的解决
Aug 06 Javascript
Node 模块原理与用法详解
May 13 #Javascript
JavaScript oncopy事件用法实例解析
May 13 #Javascript
JavaScript 正则应用详解【模式、欲查、反向引用等】
May 13 #Javascript
JavaScript 引用类型实例详解【数组、对象、严格模式等】
May 13 #Javascript
Node.js API详解之 module模块用法实例分析
May 13 #Javascript
JS如何实现手机端输入验证码效果
May 13 #Javascript
vue-socket.io接收不到数据问题的解决方法
May 13 #Javascript
You might like
ThinkPHP自定义函数解决模板标签加减运算的方法
2015/07/03 PHP
php+mysql实现简单的增删改查功能
2015/07/13 PHP
PHP+MySQL统计该库中每个表的记录数并按递减顺序排列的方法
2016/02/15 PHP
php学习笔记之mb_strstr的基本使用
2018/02/03 PHP
PHP数据源架构模式之表入口模式实例分析
2020/01/23 PHP
利用XMLHTTP传递参数在另一页面执行并刷新本页
2006/10/26 Javascript
Javascript模块模式分析
2008/05/16 Javascript
Mootools 1.2教程 Tooltips
2009/09/15 Javascript
层序遍历在ExtJs的TreePanel中的应用
2009/10/16 Javascript
解析Jquery中如何把一段html代码动态写入到DIV中(实例说明)
2013/07/09 Javascript
html+js实现动态显示本地时间
2013/09/21 Javascript
javascript使用数组的push方法完成快速排序
2014/09/15 Javascript
JavaSacript中charCodeAt()方法的使用详解
2015/06/05 Javascript
AngularJS中的过滤器使用详解
2015/06/16 Javascript
jquery实现的Banner广告收缩效果代码
2015/09/02 Javascript
全面解析Bootstrap排版使用方法(标题)
2015/11/30 Javascript
jQuery实现简单的DIV拖动效果
2016/02/19 Javascript
Jquery遍历select option和添加移除option的实现方法
2016/08/26 Javascript
JavaScript 轮播图和自定义滚动条配合鼠标滚轮分享代码贴
2016/10/28 Javascript
jQuery读取XML文件的方法示例
2017/02/03 Javascript
jQuery阻止移动端遮罩层后页面滚动
2017/03/15 Javascript
基于vue循环列表时点击跳转页面的方法
2018/08/31 Javascript
vuex的使用和简易实现
2021/01/07 Vue.js
python获取指定时间差的时间实例详解
2017/04/11 Python
Python自然语言处理之词干,词形与最大匹配算法代码详解
2017/11/16 Python
Python使用matplotlib绘制余弦的散点图示例
2018/03/14 Python
Python读取视频的两种方法(imageio和cv2)
2018/04/15 Python
在Python中获取操作系统的进程信息
2019/08/27 Python
Python 图片处理库exifread详解
2021/02/25 Python
佳能法国商店:Canon法国
2019/02/14 全球购物
Fnac西班牙官网:法国文化和电子产品零售商
2021/03/14 全球购物
金融专业毕业生自荐信
2014/06/26 职场文书
商务经理岗位职责
2014/08/03 职场文书
小学生九一八纪念日83周年演讲稿500字
2014/09/17 职场文书
工商局局长个人对照检查材料思想汇报
2014/09/23 职场文书
2016国培研修心得体会
2016/01/08 职场文书