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 相关文章推荐
Code:findPosX 和 findPosY
Dec 20 Javascript
xml分页+ajax请求数据源+dom取结果实例代码
Oct 31 Javascript
关于js中alert弹出窗口文本换行问题简单详细说明
Dec 11 Javascript
jquery简单的拖动效果实现原理及示例
Jul 26 Javascript
jQuery实现购物车数字加减效果
Mar 14 Javascript
javascript实现树形菜单的方法
Jul 17 Javascript
JavaScript操作HTML元素和样式的方法详解
Oct 21 Javascript
全面总结Javascript对数组对象的各种操作
Jan 22 Javascript
详解vue服务端渲染(SSR)初探
Jun 19 Javascript
微信小程序动态增加按钮组件
Sep 14 Javascript
详解React 服务端渲染方案完美的解决方案
Dec 14 Javascript
Vue 动态路由的实现及 Springsecurity 按钮级别的权限控制
Sep 05 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 strcmp使用说明
2010/04/22 PHP
php编程实现获取excel文档内容的代码实例
2011/06/28 PHP
Laravel等框架模型关联的可用性浅析
2019/12/15 PHP
ExtJS GTGrid 简单用户管理
2009/07/01 Javascript
javascript 获取元素位置的快速方法 getBoundingClientRect()
2009/11/26 Javascript
Jquery ThickBox插件使用心得(不建议使用)
2010/09/08 Javascript
jQuery动态设置form表单的enctype值(实现代码)
2013/07/04 Javascript
jQuery aminate方法定位到页面具体位置
2013/12/26 Javascript
删除节点的jquery代码
2014/01/13 Javascript
关于JavaScript中name的意义冲突示例介绍
2014/05/29 Javascript
Javascript定义类(class)的三种方法详解
2015/03/13 Javascript
Angularjs中如何使用filterFilter函数过滤
2016/02/06 Javascript
在angular 6中使用 less 的实例代码
2018/05/13 Javascript
JavaScript树的深度优先遍历和广度优先遍历算法示例
2018/07/30 Javascript
Javascript confirm多种使用方法解析
2020/09/25 Javascript
Python3 适合初学者学习的银行账户登录系统实例
2017/08/08 Python
python selenium firefox使用详解
2019/02/26 Python
Python TestCase中的断言方法介绍
2019/05/02 Python
python反编译学习之字节码详解
2019/05/19 Python
numpy求平均值的维度设定的例子
2019/08/24 Python
python微信公众号开发简单流程实现
2020/03/09 Python
CSS3 不定高宽垂直水平居中的几种方式
2020/03/26 HTML / CSS
原生canvas制作画图小工具的踩坑和爬坑
2020/06/09 HTML / CSS
Jo Malone美国官网:祖玛珑香水
2017/03/27 全球购物
英国鞋网:Rubber Sole
2020/03/03 全球购物
草莓网中国:StrawberryNet中国
2020/08/17 全球购物
《和我们一样享受春天》教学反思
2014/02/07 职场文书
银行服务感言
2014/03/01 职场文书
少先队学雷锋活动总结范文
2014/03/09 职场文书
《少年王冕》教学反思
2014/04/11 职场文书
《故都的秋》教学反思
2014/04/15 职场文书
mysql 8.0.24版本安装配置方法图文教程
2021/05/12 MySQL
一小时学会TensorFlow2之基本操作2实例代码
2021/09/04 Python
总结三种用 Python 作为小程序后端的方式
2022/05/02 Python
解决flex布局中子项目尺寸不受flex-shrink限制
2022/05/11 HTML / CSS
SpringBoot项目部署到阿里云服务器的实现步骤
2022/06/28 Java/Android