express.js中间件说明详解


Posted in Javascript onMarch 19, 2019

express的新开发人员往往对路由处理程序和中间件之间的区别感到困惑。因此他们也对app.use(),app.all(),app.get(),app.post(),app.delete()和app.put()方法的区别感到困惑。

在本文中,我将解释中间件和路由处理程序之间的区别。以及如何正确使用app.use(),app.all(),app.get(),app.post(),app.delete()和app.put()方法。

路由处理

app.use(),app.all(),app.get(),app.post(),app.delete()和app.put()全部是用来定义路由的。这些方法都用于定义路由。路由用于处理HTTP请求。路由是路径和回调的组合,在请求的路径匹配时执行。回调被称为路由处理程序。

它们之间的区别是处理不同类型的HTTP请求。例如: app.get()方法仅仅处理get请求,而app.all()处理GET、POST等请求。

下面是一个例子,如何定义一个路由:

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

app.get("/", function(req, res, next){
  res.send("Hello World!!!!");
});

app.listen(8080);

每个路由处理程序都获得对当前正在提供的HTTP请求的请求和响应对象的引用。

可以为单个HTTP请求执行多个路由处理程序。这是一个例子:

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

app.get("/", function(req, res, next){
  res.write("Hello");
  next();
});

app.get("/", function(req, res, next){
  res.write(" World !!!");
  res.end();
});

app.listen(8080);

这里第一个句柄写入一些响应,然后调用next()。 next()方法用于调用与路径路径匹配的下一个路由处理程序。

路由处理程序必须结束请求或调用下一个路由处理程序。

我们还可以将多个路由处理程序传递给app.all(),app.get(),app.post(),app.delete()和app.put()方法。

这是一个证明这一点的例子:

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

app.get("/", function(req, res, next){
  res.write("Hello");
  next();
}, function(req, res, next){
  res.write(" World !!!");
  res.end();
});

app.listen(8080);

中间件

中间件是一个位于实际请求处理程序之上的回调。它采用与路由处理程序相同的参数。

要了解中间件,我们来看一个带有dashboard和profile页面的示例站点。要访问这些页面,用户必须登录。还会记录对这些页面的请求。

以下是这些页面的路由处理程序的代码:

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

function checkLogin(){
  return false;
}

function logRequest(){
  console.log("New request");
}

app.get("/dashboard", function(req, res, next){

  logRequest();

  if(checkLogin()){
    res.send("This is the dashboard page");
  }
  else{
    res.send("You are not logged in!!!");
  }
});

app.get("/profile", function(req, res, next){

  logRequest();

  if(checkLogin()){
    res.send("This is the dashboard page");
  }
  else{
    res.send("You are not logged in!!!");
  }
});

app.listen(8080);

这里的问题是有很多重复的代码,即我们不得不多次使用logRequest()和checkLogin()函数。这也使得更新代码变得困难。因此,为了解决这个问题,我们可以为这两条路径编写一条通用路径。

这是重写的代码:

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

function checkLogin(){
  return false;
}

function logRequest(){
  console.log("New request");
}

app.get("/*", function(req, res, next){
  logRequest();
  next();
})

app.get("/*", function(req, res, next){
  if(checkLogin()){
    next();
  }
  else{
    res("You are not logged in!!!");
  }
})

app.get("/dashboard", function(req, res, next){
  res.send("This is the dashboard page");
});

app.get("/profile", function(req, res, next){
  res.send("This is the dashboard page");
});

app.listen(8080);

这里的代码看起来更清晰,更易于维护和更新。这里将前两个定义的路由处理程序称为中间件,因为它们不处理请求,而是负责预处理请求。

Express为我们提供了app.use()方法,该方法专门用于定义中间件。 app.use()方法可能看起来与app.all()类似,但它们之间存在很多差异,这使得app.use()非常适合于声明中间件。让我们看看app.use()方法是如何工作的:

app.use() 和 app.all() 的不同:

CALLBACK

app.use()只需要一个回调,而app.all()可以进行多次回调。

PATH

app.use()只查看url是否以指定路径开头,app.all()匹配完整路径。

这里有一个例子来说明:

app.use( "/product" , mymiddleware);
// will match /product
// will match /product/cool
// will match /product/foo

app.all( "/product" , handler);
// will match /product
// won't match /product/cool  <-- important
// won't match /product/foo  <-- important

app.all( "/product/*" , handler);
// won't match /product    <-- Important
// will match /product/cool
// will match /product/foo

NEXT()

中间件内的next()调用下一个中间件或路由处理程序,具体取决于接下来声明的那个。但是路由处理程序中的next()仅调用下一个路由处理程序。如果接下来有中间件,则跳过它。因此,必须在所有路由处理程序之前声明中间件。

这里有一个例子来说明:

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

app.use(function frontControllerMiddlewareExecuted(req, res, next){
 console.log('(1) this frontControllerMiddlewareExecuted is executed');
 next();
});

app.all('*', function(req, res, next){
 console.log('(2) route middleware for all method and path pattern "*", executed first and can do stuff before going next');
 next();
});

app.all('/hello', function(req, res, next){
 console.log('(3) route middleware for all method and path pattern "/hello", executed second and can do stuff before going next');
 next();
});

app.use(function frontControllerMiddlewareNotExecuted(req, res, next){
 console.log('(4) this frontControllerMiddlewareNotExecuted is not executed');
 next();
});

app.get('/hello', function(req, res){
 console.log('(5) route middleware for method GET and path patter "/hello", executed last and I do my stuff sending response');
 res.send('Hello World');
});

app.listen(80);

现在我们看到了app.use()方法的唯一性以及它用于声明中间件的原因。

让我们重写我们的示例站点代码:

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

function checkLogin(){
  return false;
}

function logRequest(){
  console.log("New request");
}

app.use(function(req, res, next){
  logRequest();
  next();
})

app.use(function(req, res, next){

  if(checkLogin()){
    next();
  }
  else{
    res.send("You are not logged in!!!");
  }
})

app.get("/dashboard", function(req, res, next){
  res.send("This is the dashboard page");
});

app.get("/profile", function(req, res, next){
  res.send("This is the dashboard page");
});

app.listen(8080);

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

Javascript 相关文章推荐
jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera
Aug 28 Javascript
Extjs中DisplayField的日期或者数字格式化扩展
Sep 03 Javascript
JS实现很酷的EMAIL地址添加功能实例
Feb 28 Javascript
JavaScript根据CSS的Media Queries来判断浏览设备的方法
May 10 Javascript
jQuery fadeOut 异步实例代码详解
Aug 18 Javascript
第一次动手实现bootstrap table分页效果
Sep 22 Javascript
bootstarp modal框居中显示的实现代码
Feb 18 Javascript
Vue中对比scoped css和css module的区别
May 17 Javascript
jquery使用FormData实现异步上传文件
Oct 25 jQuery
layui表格 返回的数据状态异常的解决方法
Sep 10 Javascript
vue学习笔记之slot插槽用法实例分析
Feb 29 Javascript
JavaScript 俄罗斯方块游戏实现方法与代码解释
Apr 08 Javascript
js array数组对象操作方法汇总
Mar 18 #Javascript
浅析JavaScript异步代码优化
Mar 18 #Javascript
js实现图片局部放大效果详解
Mar 18 #Javascript
详解在React项目中安装并使用Less(用法总结)
Mar 18 #Javascript
vue动画效果实现方法示例
Mar 18 #Javascript
node.js实现微信开发之获取用户授权
Mar 18 #Javascript
学习node.js 断言的使用详解
Mar 18 #Javascript
You might like
php中Smarty模板初体验
2011/08/08 PHP
PHP实现的简单网络硬盘
2015/07/29 PHP
学习php设计模式 php实现抽象工厂模式
2015/12/07 PHP
PHP实现上传多文件示例代码
2017/02/20 PHP
Yii框架日志记录Logging操作示例
2018/07/12 PHP
jquery each()源代码
2011/02/14 Javascript
JavaScript获取页面上某个元素的代码
2011/03/13 Javascript
JavaScript面向对象之Prototypes和继承
2012/07/12 Javascript
jQuery在html有效在jsp无效的原因及解决方法
2013/08/02 Javascript
[原创]Javascript 实现广告后加载 可加载百度谷歌联盟广告
2016/05/11 Javascript
Bootstrap 布局组件(全)
2016/07/18 Javascript
smartupload实现文件上传时获取表单数据(推荐)
2016/12/12 Javascript
Bootstrap滚动监听组件scrollspy.js使用方法详解
2017/07/20 Javascript
微信小程序swiper组件用法实例分析【附源码下载】
2017/12/07 Javascript
vue-content-loader内容加载器的使用方法
2018/08/05 Javascript
Vue.js的复用组件开发流程完整记录
2018/11/29 Javascript
json字符串对象转换代码实例
2019/09/28 Javascript
bootstrap+spring boot实现面包屑导航功能(前端代码)
2019/10/09 Javascript
利用React高阶组件实现一个面包屑导航的示例
2020/08/23 Javascript
[02:08]我的刀塔不可能这么可爱 胡晓桃_1
2014/06/20 DOTA
python绘图方法实例入门
2015/05/19 Python
python简单获取数组元素个数的方法
2015/07/13 Python
Python使用Beautiful Soup包编写爬虫时的一些关键点
2016/01/20 Python
python+pygame简单画板实现代码实例
2017/12/13 Python
Python生态圈图像格式转换问题(推荐)
2019/12/02 Python
Python模块future用法原理详解
2020/01/20 Python
150行Python代码实现带界面的数独游戏
2020/04/04 Python
全球速卖通巴西站点:Aliexpress巴西
2016/08/24 全球购物
Andrew Marc官网:设计师外套的领先制造商
2019/10/30 全球购物
类的核心特性有哪些
2014/01/01 面试题
大学生自助营养快餐店创业计划书
2014/01/13 职场文书
乒乓球兴趣小组活动总结
2014/07/08 职场文书
2014年调度员工作总结
2014/11/19 职场文书
2015年母亲节活动策划方案
2015/05/04 职场文书
2015年小学师德师风建设工作总结
2015/10/23 职场文书
Win11黑色桌面背景怎么办?Win11黑色壁纸解决方法汇总
2022/04/05 数码科技