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 相关文章推荐
window.showModalDialog()返回值的学习心得总结
Jan 07 Javascript
页面内容排序插件jSort使用方法
Oct 10 Javascript
详解jQuery的表单验证插件--Validation
Dec 21 Javascript
利用n工具轻松管理Node.js的版本
Apr 21 Javascript
Javascript创建类和对象详解
May 31 Javascript
详谈js中标准for循环与foreach(for in)的区别
Nov 02 Javascript
动手写一个angular版本的Message组件的方法
Dec 16 Javascript
layer实现弹出层自动调节位置
Sep 05 Javascript
js+springMVC 提交数组数据到后台的实例
Sep 21 Javascript
laravel实现中文和英语互相切换的例子
Sep 30 Javascript
vue使用showdown并实现代码区域高亮的示例代码
Oct 17 Javascript
如何使用jQuery操作Cookies方法解析
Sep 08 jQuery
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中一个控制字符串输出的函数
2006/10/09 PHP
php 强制下载文件实现代码
2013/10/28 PHP
php自定义函数实现二维数组按指定key排序的方法
2016/09/29 PHP
php实现的简单数据库操作Model类
2016/11/16 PHP
详解php中生成标准uuid(guid)的方法
2019/04/28 PHP
JavaScript 未结束的字符串常量常见解决方法
2010/01/24 Javascript
Jquery中显示隐藏的实现代码分析
2011/07/26 Javascript
Jquery实现列表(隔行换色,全选,鼠标滑过当前行)效果实例
2013/06/09 Javascript
JS如何判断是否为ie浏览器的方法(包括IE10、IE11在内)
2015/12/13 Javascript
JavaScript获取当前url根目录(路径)
2016/06/17 Javascript
详解使用vue-router进行页面切换时滚动条位置与滚动监听事件
2017/03/08 Javascript
JavaScript字符串_动力节点Java学院整理
2017/06/27 Javascript
基于jstree使用AJAX请求获取数据形成树
2017/08/29 Javascript
JS实现中文汉字按拼音排序的方法
2017/10/09 Javascript
详解如何webpack使用DllPlugin
2018/09/30 Javascript
AngularJs1.x自定义指令独立作用域的函数传入参数方法
2018/10/09 Javascript
微信小程序实现留言功能
2018/10/31 Javascript
改变layer confirm弹窗按钮的颜色方法
2019/09/12 Javascript
python检测远程服务器tcp端口的方法
2015/03/14 Python
Python实现竖排打印传单手机号码易撕条
2015/03/16 Python
Python统计一个字符串中每个字符出现了多少次的方法【字符串转换为列表再统计】
2019/05/05 Python
PyQt5 QTable插入图片并动态更新的实例
2019/06/18 Python
python读写csv文件并增加行列的实例代码
2019/08/01 Python
Python在centos7.6上安装python3.9的详细教程(默认python版本为2.7.5)
2020/10/15 Python
天美时手表加拿大官网:Timex加拿大
2016/09/01 全球购物
美国儿童运动鞋和服装零售商:Kids Foot Locker
2017/08/05 全球购物
总经理办公室主任岗位职责
2013/11/12 职场文书
孝敬父母的演讲稿
2014/05/14 职场文书
课前一分钟演讲稿
2014/08/26 职场文书
公司委托书格式范文
2014/10/09 职场文书
十佳少年事迹材料
2014/12/25 职场文书
2015年司机年终工作总结
2015/05/14 职场文书
2015年大学生暑期实习报告
2015/07/13 职场文书
培训学校2015年度工作总结
2015/07/20 职场文书
使用react+redux实现计数器功能及遇到问题
2021/06/02 Javascript
bootstrapv4轮播图去除两侧阴影及线框的方法
2022/02/15 HTML / CSS