NodeJS / Express:什么是“ app.use”?


332

NodeJS express模块文档中,示例代码包含app.use(...)

什么是use功能,它在哪儿定义?



这些类型的问题可以通过阅读文档来回答。
米娜

47
该文档对于初学者来说有点神秘
KansaiRobot

6
上面可能重复的项目互相引用
Afrig Aminuddin

1
文档是完全不清楚的
Tessaracter

Answers:


369

app对象在创建Express服务器时实例化。它具有可以在其中定制的中间件堆栈app.configure()(现在在4.x版本中已弃用)

要设置中间件,您可以app.use(<specific_middleware_layer_here>)为要添加的每个中间件层调用(可以对所有路径通用,也可以仅在服务器处理的特定路径上触发),并将其添加到Express中间件堆栈中。中间件层可以在的多个调用中一个接一个地添加use,甚至可以一次调用一次全部添加。有关更多详细信息,请参见use文档

为了提供对Express Middleware的概念性理解的示例,以下是将我的应用程序对象作为JSON登录到控制台时我的应用程序中间件堆栈(app.stack)的外观:

stack: 
   [ { route: '', handle: [Function] },
     { route: '', handle: [Function: static] },
     { route: '', handle: [Function: bodyParser] },
     { route: '', handle: [Function: cookieParser] },
     { route: '', handle: [Function: session] },
     { route: '', handle: [Function: methodOverride] },
     { route: '', handle: [Function] },
     { route: '', handle: [Function] } ]

您可能可以推断出,我叫app.use(express.bodyParser())app.use(express.cookieParser())等,这将这些表达中间件“层”添加到中间件堆栈中。注意,这些路由是空白的,这意味着当我添加这些中间件层时,我指定了它们会在任何路由上触发。如果我添加了一个仅在路径/user/:id上触发的自定义中间件层,该路径将route在上面的堆栈打印输出中的那个中间件层对象的字段中反映为字符串。

每层本质上都添加了一个功能,该功能专门处理通过中间件的流程中的某些内容。

例如通过添加bodyParser您确保服务器通过快速中间件处理传入的请求。因此,现在解析传入请求的主体是中间件在处理传入请求时所采用的过程的一部分 -全部是因为您调用了app.use(bodyParser)


116
谢谢。快递人员在他们的API文档中解释这一点会很难吗?
ericsoco

4
因此,您说的是,当收到请求时,数据将在到达实际服务之前通过这些解析器传递。因此,例如:Valid Request-> Authentication-> ProcessesRequest-> ServResponse USE是否会按特定顺序控制这些步骤,而不并行执行?
亚当·赫斯

2
那么app.use()依赖注入在起作用吗?
凯文C.

8
发送到app.use的函数何时调用?创建快递服务器后还是针对每个请求?
Timo Huovinen

5
@KevinC。不,这不是依赖项注入。这是一个插件架构。通常,这种架构称为过滤器系统/过滤器管道/管道和过滤器。在Express中,管道是next()每个中间件都应调用的回调,以将处理传递给管道中的下一个函数。路由系统(的第一个参数app.use())允许管道根据URL进行分支
slebetman

50

use是一种配置Express HTTP服务器对象的路由所使用的中间件的方法。该方法定义为Express基于的Connect的一部分。

更新从版本4.x开始,Express不再依赖Connect

Express以前包含的中间件功能现在位于单独的模块中;请参阅中间件功能列表



如果Node中间件实例化对象,效率会很高吗?这是否意味着在每个请求中,中间件都会实例化新对象?旧物件会被丢弃吗?例如app.use(function(){ var object = new SomeConstructor; next(); })
CMCDragonkai 2014年

1
@CMCDragonkai可以在每个请求上实例化对象。只要您不存储对请求处理程序范围之外的对象的引用,它们就会被垃圾收集。
jeff_mcmahan 2015年

1
@AlexanderBird thx的链接(虽然第一个已损坏)。为了便于记录,仅在第二个链接中文档的开头显示“将给定路由使用给定的中间件句柄,默认为/。当给定的值不是/时,此“ route”是中间件的安装点。中间件仅在请求的路径名中存在该段时才有效。例如,如果我们要在/ admin上挂载一个函数,则将在/ admin和/ admin / settings上调用该函数,但是对于/ ,或/ posts”。简单:)
阿德里安

40

每次将请求发送到服务器时,都会调用每个app.use(middleware)


7
您的单句答案可立即理解,比其他多段落解释更有用。
StackedAndOverflowed

16

app.use()用于挂载中间件功能或挂载到指定路径,当基本路径匹配时执行中间件功能。

例如: 如果您在indexRouter.js中使用app.use(),如下所示:

//indexRouter.js

var adsRouter = require('./adsRouter.js');

module.exports = function(app) {
    app.use('/ads', adsRouter);
}

在上面的代码app.use()中,将路径“ / ads”安装到adsRouter.js。

现在在adsRouter.js中

// adsRouter.js

var router = require('express').Router();
var controllerIndex = require('../controller/index');
router.post('/show', controllerIndex.ads.showAd);
module.exports = router;

在adsRouter.js中,广告'/ ads / show'的路径将是这样,然后它将根据controllerIndex.ads.showAd()运行。

app.use([path],callback,[callback]): 我们可以在其上添加一个回调。

app.use('/test', function(req, res, next) {

  // write your callback code here.

    });

我会用“ map”代替“ mount”,这更容易理解。
Jeb50

13

app.use()在快速应用程序中充当中间件。与app.get()app.post()左右不同,您实际上可以使用app.use()而不指定请求URL。在这种情况下,无论点击哪个URL,它都会每次执行。


7

app.use()的工作方式如下:

  1. 在节点http服务器实例上触发的请求事件。
  2. express对req对象进行一些内部操作。
  3. 这是Express开始执行您通过app.use指定的操作时的时间

这很简单。

然后只有express才能完成路由之类的其余工作。


6
app.use(function middleware1(req, res, next){
   // middleware1 logic
}, function middleware1(req, res, next){
   // middleware2 logic
}, ... middlewareN);

app.use是一种根据中间件注册序列的顺序在执行任何最终路由逻辑或中间路由逻辑之前注册中间件或中间件链(或多个中间件)的方法。

中间件:形成带有3个参数req,res和next功能/中间件功能链。next是回调,它引用链中的下一个中间件功能,在链的最后一个中间件功能的情况下,next指向下一个注册的中间稀有链的first-middleware-function。


1
奇迹般有效 !!
Anmol Rai

3

在express中,如果我们从“ express”导入express并使用app = express(); 然后具有快速表达所有功能的应用

如果我们使用app.use()

具有任何模块/中间件功能,可用于整个快递项目


3

app.use是需要中间件的功能。例如:

 app.use('/user/:id', function (req, res, next) {
       console.log('Request Type:', req.method);
        next();
     });

此示例显示了/user/:id路径中安装的中间件功能。此功能针对/user/:id路径中的任何类型的HTTP请求执行。

它类似于REST Web服务器,只是使用不同/xx的代表不同的动作。


感谢您的回答,但由于其他人已经说了所有这些信息,因此我不会对此表示支持。我不需要我对快递use可以做什么做任何解释。我只需要知道那是什么(以及任何上下文知识就可以自己进行更多研究)。
亚历山大·伯德

3

app.use可以作为应用程序请求的中间件。句法

app.use('pass request format',function which contain request response onject)

app.use('/',funtion(req,res){
 console.log(all request pass through it);
// here u can check your authentication and other activities.
})

您也可以在路由请求时使用它。

app.use('/', roting_object);

2

中间件是用于“粘合在一起”的软件的通用术语,因此app.use是一种配置中间件的方法,例如:解析和处理请求主体:app.use(bodyParser.urlencoded({ })); app.use(bodyParser.json()); 只需阅读doc,您就可以在快速应用程序中使用许多中间件:http : //expressjs.com/en/guide/using-middleware.html


2

app.use将指定的中间件应用于主应用程序中间件堆栈。将中间件附加到主应用程序堆栈时,附加顺序很重要;如果您在中间件B之前附加了中间件A,则中间件A将始终首先执行。您可以指定特定中间件适用的路径。在下面的示例中,“ hello world”将始终在“节日快乐”之前记录。

const express = require('express')
const app = express()

app.use(function(req, res, next) {
  console.log('hello world')
  next()
})

app.use(function(req, res, next) {
  console.log('happy holidays')
  next()
})

2

它可以让你使用任何中间件(阅读更多)一样body_parserCORS等中间件可以修改requestresponse对象。它也可以执行一段代码。


感谢您的回答,但我相信所有其他回答都已经包含了所有信息
Alexander Bird

2

您还可以创建自己的中间件功能,例如

app.use( function(req, res, next) {
  // your code 
  next();
})

它包含三个参数reqresnext
你也可以用它来验证和输入则params的验证,以保持控制器的清洁。

next()用于转到下一个中​​间件或路由。
您可以从中间件发送响应



1

简而言之,app.use()支持所有类型的请求[例如:get,post,...],因此它主要用于设置中间件。或可用于路线和功能分开的情况

例:

app.use("/test",functionName)

和functionName位于不同的文件中


感谢您提供答案,但我相信所有其他答案中都已经包含了所有信息。
亚历山大·伯德

1

app.use() 是一种中间件方法。

中间件方法就像Java中的拦截器一样,该方法始终针对所有请求执行。

中间件的目的和使用:

  1. 检查会话是否过期
  2. 用于用户身份验证和授权
  3. 检查Cookie(有效期)
  4. 响应前解析数据

中间件是传递给app.use()的函数。
NattyC

1

app.use
由express(nodejs中间件框架)
创建。app.use用于在渗透过程中执行任何特定的查询
server.js(node)
var app = require('express'); 所以基本上app.use函数每次服务器启动时都会调用
app.use(bodyparser.json())


0

app.use是应用程序级中间件

使用app.use()和app.METHOD()函数将应用程序级中间件绑定到app对象的实例,其中METHOD是中间件函数处理的请求的HTTP方法(例如GET,PUT或POST)(小写)。

您可以用来检查所有请求,例如,要检查令牌/访问令牌,需要使用app.use编写中间件,以检查请求中的令牌。

此示例显示了没有安装路径的中间件功能。每次应用收到请求时,都会执行该功能。

var app = express()

app.use(function (req, res, next) {
  console.log('Time:', Date.now())
  next()
})

来自https://expressjs.com/en/guide/using-middleware.html的参考


app.use()不是中间件。中间件是传递给app.use()的函数
NattyC

0

app.use(path,middleware)用于调用中间件功能,该功能需要在为相应路径命中路由之前被调用。可以通过app.use调用多个中间件功能。

app.use('/ fetch',forceenAuthentication) ->强制身份验证中间件fn将在收到以'/ fetch'开头的请求时被调用。它可以是 / fetch / users / fetch / ids / {id}

无论请求如何,都可能必须调用某些中间件功能。在这种情况下,未指定路径,并且由于该路径默认为/且每个请求均以/开头,因此将为所有请求调用此中间件功能。

app.use(()=> {//初始化公共服务})

当多个中间件函数传递给app.use时,需要在每个中间件函数内调用next() fn ,否则不会调用下一个中间件函数。

参考:http : //expressjs.com/en/api.html#app.use

注意:文档说,我们可以通过在当前中间件函数中调用next('route')绕过当前中间件函数,但是该技术在app.use中对我不起作用,对app.METHOD起作用,如下所示。因此,调用了fn1和fn2,但未调用fn3。

app.get('/fetch', function fn1(req, res, next)  {
    console.log("First middleware function called"); 
        next();
    }, 
    function fn2(req, res, next) {
        console.log("Second middleware function called"); 
        next("route");
    }, 
    function fn3(req, res, next) {
        console.log("Third middleware function will not be called"); 
        next();
    })
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.