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 相关文章推荐
19个很有用的 JavaScript库推荐
Jun 27 Javascript
通过下拉框的值来确定输入框是否可以为空的代码
Oct 18 Javascript
javascript阻止scroll事件多次执行的思路及实现
Nov 08 Javascript
JavaScript对内存分配及管理机制详细解析
Nov 11 Javascript
JS显示表格内指定行html代码的方法
Mar 31 Javascript
JavaScript获取URL汇总
Jun 08 Javascript
jQuery点击其他地方时菜单消失的实现方法
Apr 22 Javascript
浅谈jquery.form.js的ajaxSubmit和ajaxForm的使用
Sep 09 Javascript
Bootstrap面板使用方法
Jan 16 Javascript
详解Vue SSR( Vue2 + Koa2 + Webpack4)配置指南
Nov 13 Javascript
layui实现下拉框三级联动
Jul 26 Javascript
利用前端HTML+CSS+JS开发简单的TODOLIST功能(记事本)
Apr 13 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
ajax缓存问题解决途径
2006/12/06 PHP
用PHP生成静态HTML速度快类库
2007/03/18 PHP
PHP数组去重比较快的实现方式
2016/01/19 PHP
针对PHP开发安全问题的相关总结
2019/03/22 PHP
PHP面向对象程序设计子类扩展父类(子类重新载入父类)操作详解
2019/06/14 PHP
CSS心形加载的动画源码的实现
2021/03/09 HTML / CSS
xml 与javascript结合的问题解决方法
2007/03/24 Javascript
一个简单的Ext.XTemplate的实例代码
2012/03/18 Javascript
JS 修改URL参数(实现代码)
2013/07/08 Javascript
JS小功能(button选择颜色)简单实例
2013/11/29 Javascript
js获取鼠标点击的位置实现思路及代码
2014/05/09 Javascript
Javascript动画的实现原理浅析
2015/03/02 Javascript
javascript判断css3动画结束 css3动画结束的回调函数
2015/03/10 Javascript
浅谈JS继承_借用构造函数 &amp; 组合式继承
2016/08/16 Javascript
vue.js实现请求数据的方法示例
2017/02/07 Javascript
浅谈jQuery的bind和unbind事件(绑定和解绑事件)
2017/03/02 Javascript
JS查找数组中重复元素的方法详解
2017/06/14 Javascript
Angular2里获取(input file)上传文件的内容的方法
2017/09/05 Javascript
微信小程序实现循环动画效果
2018/07/16 Javascript
mpvue实现左侧导航与右侧内容的联动
2019/10/21 Javascript
vue-element-admin 菜单标签失效的解决方式
2019/11/12 Javascript
微信小程序顶部导航栏可滑动并选中放大
2019/12/05 Javascript
json.stringify()与json.parse()的区别以及用处
2021/01/25 Javascript
Python判断变量是否已经定义的方法
2014/08/18 Python
python字符串查找函数的用法详解
2019/07/08 Python
keras获得某一层或者某层权重的输出实例
2020/01/24 Python
python collections模块的使用
2020/10/16 Python
html5 web本地存储将取代我们的cookie
2012/12/26 HTML / CSS
澳大利亚家具和家居用品在线:BROSA
2017/11/02 全球购物
团员个人的自我评价
2013/12/02 职场文书
英语演讲稿范文
2014/01/03 职场文书
超市活动计划书
2014/04/24 职场文书
自主招生学校推荐信
2014/09/26 职场文书
夫妻分居协议书范文
2014/11/26 职场文书
单位实习介绍信
2015/05/05 职场文书
超外差式晶体管收音机的组装与统调
2021/04/22 无线电