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 模式对话框终极版实现代码
Sep 28 Javascript
我遇到的参数传递中 双引号单引号嵌套问题
Feb 11 Javascript
JS链式调用的实现方法
Mar 07 Javascript
防止浏览器记住用户名及密码的简单实用方法
Apr 22 Javascript
jquery简单实现滚动条下拉DIV固定在头部不动
Nov 25 Javascript
FireBug 调试JS入门教程 如何调试JS
Dec 23 Javascript
下雪了 javascript实现雪花飞舞
Aug 02 Javascript
浅谈window.onbeforeunload() 事件调用ajax
Jun 29 Javascript
详解微信小程序 wx.uploadFile 的编码坑
Jan 23 Javascript
在create-react-app中使用css modules的示例代码
Jul 31 Javascript
vue封装swiper代码实例解析
Oct 08 Javascript
javascript实现扫雷简易版
Aug 18 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下实现一个阿拉伯数字转中文数字的函数
2008/07/10 PHP
C#使用PHP服务端的Web Service通信实例
2014/04/08 PHP
php微信公众平台开发(一) 配置接口
2016/12/06 PHP
Extjs学习笔记之九 数据模型(上)
2010/01/11 Javascript
ExtJS4利根据登录后不同的角色分配不同的树形菜单
2014/05/02 Javascript
页面刷新时记住滚动条的位置jquery代码
2014/06/17 Javascript
JavaScript函数作用域链分析
2015/02/13 Javascript
JavaScript AOP编程实例
2015/06/16 Javascript
Javascript removeChild()删除节点及删除子节点的方法
2015/12/27 Javascript
JavaScript实现数据类型的相互转换
2016/03/06 Javascript
jquery模拟多级复选框效果的简单实例
2016/06/08 Javascript
JS中的作用域链
2017/03/01 Javascript
javascript 开发之百度地图使用到的js函数整理
2017/05/19 Javascript
vue-router重定向和路由别名的使用讲解
2019/01/19 Javascript
Vue 组件参数校验与非props特性的方法
2019/02/12 Javascript
浅谈js中的bind
2019/03/18 Javascript
js实现数字从零慢慢增加到指定数字示例
2019/11/07 Javascript
vue+elementUI 实现内容区域高度自适应的示例
2020/09/26 Javascript
pygame学习笔记(4):声音控制
2015/04/15 Python
pandas 数据归一化以及行删除例程的方法
2018/11/10 Python
在win10和linux上分别安装Python虚拟环境的方法步骤
2019/05/09 Python
python爬虫基础之urllib的使用
2020/12/31 Python
python中if嵌套命令实例讲解
2021/02/25 Python
Expedia印度尼西亚站:预订酒店、廉价航班和度假套餐
2018/01/31 全球购物
Ralph Lauren意大利官方网站:时尚界最负盛名的品牌之一
2018/10/18 全球购物
斯巴达比赛商店:Spartan Race
2019/01/08 全球购物
荷兰游戏商店:Allyouplay
2019/03/16 全球购物
夜大毕业生自我评价分享
2013/11/10 职场文书
宣传活动总结范文
2014/07/01 职场文书
关于感谢信的范文
2015/01/23 职场文书
2015年感恩母亲节活动方案
2015/05/04 职场文书
CAD实训总结范文
2015/08/03 职场文书
大学生团支书竞选稿
2015/11/21 职场文书
2016年12月份红领巾广播稿
2015/12/21 职场文书
八年级作文之友谊
2019/12/02 职场文书
APP界面设计技巧和注意事项
2022/04/29 杂记