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(jquery)利用函数修改全局变量的代码
Nov 02 Javascript
HTA版JSMin(省略修饰语若干)基于javascript语言编写
Dec 24 Javascript
深入document.write()与HTML4.01的非成对标签的详解
May 08 Javascript
继续学习javascript闭包
Dec 03 Javascript
js严格模式总结(分享)
Aug 22 Javascript
Javascript中常用的检测方法小结
Oct 08 Javascript
Angular2学习笔记——详解路由器模型(Router)
Dec 02 Javascript
javascript 使用正则test( )第一次是 true,第二次是false
Feb 22 Javascript
JavaScript标准对象_动力节点Java学院整理
Jun 27 Javascript
Angular6新特性之Angular Material
Dec 28 Javascript
vue中$nextTick的用法讲解
Jan 17 Javascript
详解webpack 最简打包结果分析
Feb 20 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
PHP下10件你也许并不了解的事情
2008/09/11 PHP
防止用户利用PHP代码DOS造成用光网络带宽
2011/03/01 PHP
php获取用户IPv4或IPv6地址的代码
2012/11/15 PHP
php图片上传类 附调用方法
2016/05/15 PHP
php微信开发之谷歌测距
2018/06/14 PHP
php查看一个变量的占用内存的实例代码
2020/03/29 PHP
pjblog修改技巧汇总
2007/03/12 Javascript
event对象的方法 兼容多浏览器
2009/06/27 Javascript
面向对象的Javascript之一(初识Javascript)
2012/01/20 Javascript
jQuery 获取兄弟元素的几种不错方法
2014/05/23 Javascript
原生JS绑定滑轮滚动事件兼容常见浏览器
2014/06/30 Javascript
Javascript中的Prototype到底是什么
2016/02/16 Javascript
如何消除inline-block属性带来的标签间间隙
2016/03/31 Javascript
js动态获取子复选项并设计全选及提交的实现方法
2016/06/24 Javascript
javascript中闭包概念与用法深入理解
2016/12/15 Javascript
微信小程序 Toast自定义实例详解
2017/01/20 Javascript
微信小程序 合法域名校验出错详解及解决办法
2017/03/09 Javascript
vue 和vue-touch 实现移动端左右导航效果(仿京东移动站导航)
2017/04/22 Javascript
浅谈在koa2中实现页面渲染的全局数据
2017/10/09 Javascript
js实现鼠标移动到图片产生遮罩效果
2017/10/21 Javascript
微信小程序实时聊天WebSocket
2018/07/05 Javascript
vue实现pdf导出解决生成canvas模糊等问题(推荐)
2018/10/18 Javascript
微信小程序实现发送验证码按钮效果
2018/12/20 Javascript
[46:43]DOTA2上海特级锦标赛主赛事日 - 1 胜者组第一轮#2LGD VS MVP.Phx第二局
2016/03/02 DOTA
python获取当前用户的主目录路径方法(推荐)
2017/01/12 Python
深入浅析python with语句简介
2018/04/11 Python
Python requests模块实例用法
2019/02/11 Python
numpy.random模块用法总结
2019/05/27 Python
python基于pdfminer库提取pdf文字代码实例
2019/08/15 Python
Django 实现 Websocket 广播、点对点发送消息的代码
2020/06/03 Python
周仰杰(JIMMY CHOO)法国官方网站:闻名世界的鞋子品牌
2019/09/27 全球购物
护士检查书
2014/01/17 职场文书
班组拓展活动方案
2014/08/14 职场文书
镇班子对照检查材料思想汇报
2014/09/24 职场文书
党支部2014年度工作总结
2014/12/04 职场文书
大学生考试作弊被抓检讨书
2014/12/27 职场文书