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 相关文章推荐
javascript 读取XML数据,在页面中展现、编辑、保存的实现
Oct 27 Javascript
jQuery 选择器、DOM操作、事件、动画
Nov 25 Javascript
ExtJS4 表格的嵌套 rowExpander应用
May 02 Javascript
js实现鼠标悬停图片上时滚动文字说明的方法
Feb 17 Javascript
JavaScript原生对象之Date对象的属性和方法详解
Mar 13 Javascript
一个用jquery写的判断div滚动条到底部的方法【推荐】
Apr 29 Javascript
JavaScript中 ES6 generator数据类型详解
Aug 11 Javascript
selenium 与 chrome 进行qq登录并发邮件操作实例详解
Apr 06 Javascript
轻量级富文本编辑器wangEditor结合vue使用方法示例
Oct 10 Javascript
小程序云开发初探(小结)
Oct 24 Javascript
Javascript Dom元素获取和添加详解
Sep 24 Javascript
Vue.js中Line第三方登录api的实现代码
Jun 29 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删除数组中的特定元素的代码
2012/06/28 PHP
php中explode的负数limit用法分析
2015/02/27 PHP
PHP list() 将数组中的值赋给变量的简单实例
2016/06/13 PHP
php使用preg_match()函数验证ip地址的方法
2017/01/07 PHP
PHP的RSA加密解密方法以及开发接口使用
2018/02/11 PHP
PHPUnit测试私有属性和方法功能示例
2018/06/12 PHP
二级域名转向类
2006/11/09 Javascript
理解JavaScript的caller,callee,call,apply
2009/04/28 Javascript
基于jquery跨浏览器显示的file上传控件
2011/10/24 Javascript
javaScript面向对象继承方法经典实现
2013/08/20 Javascript
首页图片漂浮效果示例代码
2014/06/05 Javascript
js生成的验证码的实现与技术分析
2014/09/17 Javascript
node.js调用C++开发的模块实例
2015/07/03 Javascript
用window.onerror捕获并上报Js错误的方法
2016/01/27 Javascript
javascript动画系列之模拟滚动条
2016/12/13 Javascript
Vue.js中该如何自己维护路由跳转记录
2019/05/19 Javascript
vue实现记事本功能
2019/06/26 Javascript
python 从远程服务器下载东西的代码
2013/02/10 Python
Python常用小技巧总结
2015/06/01 Python
Python中的字符串操作和编码Unicode详解
2017/01/18 Python
Python深度优先算法生成迷宫
2018/01/22 Python
用Python识别人脸,人种等各种信息
2019/07/15 Python
django基础学习之send_mail功能
2019/08/07 Python
Python 基于wxpy库实现微信添加好友功能(简洁)
2019/11/29 Python
解决django接口无法通过ip进行访问的问题
2020/03/27 Python
生物科学专业个人求职信范文
2013/12/05 职场文书
银行职业规划书范文
2013/12/28 职场文书
饭店工作计划书
2014/01/10 职场文书
小学毕业感言300字
2014/02/19 职场文书
家长通知书家长评语
2014/04/17 职场文书
教导主任竞聘演讲稿
2014/05/16 职场文书
小学班级特色活动方案
2014/08/31 职场文书
户籍证明书标准模板
2014/09/10 职场文书
推销搭讪开场白
2015/05/28 职场文书
Python 语言实现六大查找算法
2021/06/30 Python
Python基础 括号()[]{}的详解
2021/11/07 Python