深入理解nodejs中Express的中间件


Posted in NodeJs onMay 19, 2017

Express是一个基于Node.js平台的web应用开发框架,在Node.js基础之上扩展了web应用开发所需要的基础功能,从而使得我们开发Web应用更加方便、更加快捷。

举一个例子:

用node.js实现一个控制台打印“hello server”

var http = require('http');
var server = http.createServer(function(req,res){
 console.log("hello server");
});
server.listen(3000);

这样子的话,当我们需要处理各种请求(主要指GET、POST)时,我们需要将所有请求类型处理的代码写在createServer包裹的函数里。

用Express实现一个控制台打印“hello server”

var express = require('express');
var app = express();
http.createServer(app);
 
// 处理用户请求(路由)
app.get("/",function(){
 console.log("hello server");
})

Express处理各种请求是通过Express执行函数去调用对应的方法,这样是不是更加方便和快捷了。

Express的API文档完整易懂,2010-01-03陆续发布了几个版本,其中第三版和第四版差异比较大, 主要体现在第三版的中间件基本上都是继承了connect框架的,而第四版将中间件独立出来了,不在依赖connect框架。

说到中间件,官网对它的阐述是这样的:

“Express是一个自身功能极简,完全是路由和中间件构成一个web开发框架:从本质上来说,一个Express应用就是在调用各种中间件。”

由此可见,中间件在Express开发中的重要性,因此这里我们就专门来总结一下中间件。

一、中间件结构

1、app.use([path],function)

path:是路由的url,默认参数‘/',意义是路由到这个路径时使用这个中间件

function:中间件函数

这个中间件函数可以理解为就是function(request,response,next)

这里安装是指涉及到第三方中间件的使用时,需要先安装好,然后在使用。

二、中间件分类

1、内置中间件

 express.static 是Express目前唯一内置的一个中间件。用来处理静态资源文件。

什么意思了? 来run一下代码看看

// index.js
var express = require('express');
var app = express();
 
app.use(express.static(__dirname + '/public'));

启动服务: node index.js

浏览器中访问: http://localhost:1234/ 展示的/public/index.html内容

浏览器中访问: http://localhost:1234/hello.html 展示的/public/hello.html内容

2、自定义中间件

在上面中间件结构中,我们知道了,中间件使用时的第二个参数是一个Function,然而,要自定义一个中间件,就是倒腾一番这个Function。

这个function总共有三个参数(req,res,next);

当每个请求到达服务器时,nodejs会为请求创建一个请求对象(request),该请求对象包含客户端提交上来的数据。同时也会创建一个响应对象(response),响应对象主要负责将服务器的数据响应到客户端。而最后一个参数next是一个方法,因为一个应用中可以使用多个中间件,而要想运行下一个中间件,那么上一个中间件必须运行next()。

好了,有了一个大概的了解,下面我定义一些中间件来实现一个路由功能。

var express = require('express');
var app = express();
 
app.use(function(request,response,next){
 if(request.url === '/'){
  response.writeHead(200,{"Content-Type":"text/plain"});
  response.end("This is home\n");
 } else {
  next();
 }
})
app.use(function(request,response,next){
 if(request.url === '/about'){
  response.writeHead(200,{"Content-Type":"text/plain"});
  response.end("This is about\n");
 } else {
  next();
 }
})
app.use(function(request,response,next){
 response.writeHead(404,{"Content-Type":"text/plain"});
 response.end("404 not found!\n");
})
app.listen(1234,'localhost');

浏览器中访问: http://localhost:1234/ 展示This is home

浏览器中访问: http://localhost:1234/about 展示This is about

这样看是不是使用中间件很轻松就实现了路由的功能,当然,有关Express的路由可以专门拿出来写写,哈哈。

3、第三方中间件

有关第三方中间件,这里我们分析几个比较重要和常用的,知道这几个的使用,其它的也就会了。

body-parser :解析body中的数据,并将其保存为Request对象的body属性。

cookie-parser :解析客户端cookie中的数据,并将其保存为Request对象的cookie属性

express-session :解析服务端生成的sessionid对应的session数据,并将其保存为Request对象的session属性

query:这个中间件将一个查询字符串从URL转换为JS对象,并将其保存为Request对象的query属性。这个中间件在第四个版本中已经内置了无需安装。

下面来一个例子,功能是:用户可否登录和在服务端保存登录态。

var express = require('express');
// 引入模板引擎
var hbs = require('express-handlebars');
var bodyParser = require('body-parser');
var session = require('express-session');
 
var app = express();
 
// hbs是一个模板引擎
app.engine('hbs',hbs());
app.set('view engine','hbs');
app.set('views','templates');
 
// 数据库读出来的数据
var userArr = ['wpzheng'];
 
app.use(session({secret:'maizidu'}));
app.use(bodyParser.urlencoded({extended:true}));
 
app.get('/', function(request,response,next){
 var username = request.session.username;
 if(username){
  response.send("hello" + username);
 }else{
  response.render('form');
 }
});
 
app.post('/', function(request,response){
  if(userArr.indexOf(request.body.username)>=0){
   request.session.username = request.body.username;
  }else{
   request.session.destroy();
  }
    // response对象的一个方法 重定向作用
  response.redirect('/');
});
app.listen(1234,'localhost');

如果session没有保存数据(测试时可以将服务关闭,session就没有值了,每次向服务器发送请求时,服务会创建一个新的session),就会自动跳到登录页面。当已登录过(也就是说有session值),就直接显示username。

这个例子涉及到模板(hbs)和response的方法(redirect)可以先不管。

三、中间件理解

写到最后了,回到最开始的问题,你是否理解了什么是Express中间件?

结合上面讲解时给出的例子,我们先来分析一下从浏览器地址栏输入url到客户端显示数据之间这个过程到底发生了什么。

深入理解nodejs中Express的中间件

浏览器向服务器发送一个请求后,服务器直接通过request.定位属性的方式得到通过request携带过去的数据(有用户输入的数据和浏览器本身的数据信息)。这中间就一定有一个函数将这些数据分类做了处理,已经处理好了,最后让request对象调用使用,对的,这个处理数据处理函数就是我们要说的 中间件 。由此可见,中间件可以总结以下几点:

1、封装了一些处理一个完整事件的功能函数。

2、非内置的中间件需要通过安装后,require到文件就可以运行。

3、封装了一些或许复杂但肯定是通用的功能。

以上所有代码下载:https://github.com/wenpingzheng/express-js.git

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

NodeJs 相关文章推荐
NodeJS框架Express的模板视图机制分析
Jul 19 NodeJs
浅谈NodeJS中require路径问题
May 07 NodeJs
详解Nodejs的timers模块
Dec 22 NodeJs
初探nodeJS
Jan 24 NodeJs
nodejs操作mysql实现增删改查的实例
May 28 NodeJs
nodejs socket实现的服务端和客户端功能示例
Jun 02 NodeJs
使用Nodejs连接mongodb数据库的实现代码
Aug 21 NodeJs
nodejs Assert中equal(),strictEqual(),deepEqual(),strictDeepEqual()比较
Sep 18 NodeJs
Linux Centos7.2下安装nodejs&npm配置全局路径的教程
May 15 NodeJs
NodeJs 文件系统操作模块fs使用方法详解
Nov 26 NodeJs
nodejs通过钉钉群机器人推送消息的实现代码
May 05 NodeJs
Nodejs封装类似express框架的路由实例详解
Jan 05 NodeJs
nodejs批量下载图片的实现方法
May 19 #NodeJs
nodejs制作爬虫实现批量下载图片
May 19 #NodeJs
详解Windows下安装Nodejs步骤
May 18 #NodeJs
nodejs+websocket实时聊天系统改进版
May 18 #NodeJs
nodejs6下使用koa2框架实例
May 18 #NodeJs
Nodejs中使用captchapng模块生成图片验证码
May 18 #NodeJs
详解使用nodeJs安装Vue-cli
May 17 #NodeJs
You might like
smarty+adodb+部分自定义类的php开发模式
2006/12/31 PHP
人尽可用的Windows技巧小贴士之下篇
2007/03/22 PHP
web站点获取用户IP的安全方法 HTTP_X_FORWARDED_FOR检验
2013/06/01 PHP
php中spl_autoload详解
2014/10/17 PHP
四种php中webservice实现的简单架构方法及实例
2015/02/03 PHP
PHP基于反射机制实现插件的可插拔设计详解
2016/11/10 PHP
Laravel框架基础语法与知识点整理【模板变量、输出、include引入子视图等】
2019/12/03 PHP
tp5.0框架隐藏index.php入口文件及模块和控制器的方法分析
2020/02/11 PHP
JavaScript中的View-Model使用介绍
2011/08/11 Javascript
基于jquery的图片轮播 tab切换组件
2012/07/19 Javascript
jQuery实现鼠标滑过遮罩并高亮显示效果
2013/07/16 Javascript
js兼容pc端浏览器并有多种弹出小提示的手机端浮层控件实例
2015/04/29 Javascript
JavaScript中获取纯正的undefined的方法
2016/03/06 Javascript
基于javascript数组实现图片轮播
2016/05/02 Javascript
用jQuery的AJax实现异步访问、异步加载
2016/11/02 Javascript
String字符串截取的四种方式总结
2016/11/28 Javascript
jQuery使用ajax方法解析返回的json数据功能示例
2017/01/10 Javascript
Js实现京东无延迟菜单效果实例(demo)
2017/06/02 Javascript
Vue实现浏览器打印功能的代码
2020/04/17 Javascript
Vue.js获取手机系统型号、版本、浏览器类型的示例代码
2020/05/10 Javascript
[59:36]2018DOTA2亚洲邀请赛 4.3 突围赛 Secret vs VG 第二场
2018/04/04 DOTA
python实现封装得到virustotal扫描结果
2014/10/05 Python
python将ip地址转换成整数的方法
2015/03/17 Python
Python使用matplotlib模块绘制图像并设置标题与坐标轴等信息示例
2018/05/04 Python
python虚拟环境完美部署教程
2019/08/06 Python
Tensorflow之梯度裁剪的实现示例
2020/03/08 Python
html5 web本地存储将取代我们的cookie
2012/12/26 HTML / CSS
广告学专业应届生求职信
2013/10/01 职场文书
自动化专业个人求职信范文
2013/11/29 职场文书
金属材料工程个人求职的自我评价
2013/12/04 职场文书
学校安全工作制度
2014/01/19 职场文书
餐饮企业总经理岗位职责范文
2014/02/18 职场文书
运动会广播稿100字
2014/09/14 职场文书
2014幼儿园小班工作总结
2014/11/10 职场文书
小学生暑假生活总结
2015/07/13 职场文书
PC版《死亡搁浅导剪版》现已发售 展开全新的探险
2022/04/03 其他游戏