app.all('*') VS app.use(function) 的区别?

sdf*_*sdf 2 routes node.js express

app.all('*', function(req, res, next) { 
Run Code Online (Sandbox Code Playgroud)

对比

app.use(function (req, res, next) {
Run Code Online (Sandbox Code Playgroud)

有什么不同?不都接受对服务器的每个请求吗?

jfr*_*d00 5

对于通配符*路径,实际上根本没有太大的意义差异。在我看来,内部实现对于app.use(fn), 那么app.all('*', fn). 而且,如果您打算让它在所有路线上运行,那么app.use()对我来说更合乎逻辑,因为您真正在做的是中间件,而这app.use()正是专门为之设计的。

app.all('*', fn)vs 的总结app.use(fn)

  1. 执行顺序没有区别。
  2. app.use()无论方法如何都会触发,app.all()仅对解析器支持的方法触发(可能不相关,因为 node.js http 解析器支持所有预期的方法)。

app.all('/test', fn)vs 的总结app.use('/test', fn)

  1. 执行顺序没有区别
  2. app.use()无论方法如何都会触发,app.all()仅对解析器支持的方法触发(可能不相关,因为 node.js http 解析器支持所有预期的方法)。
  3. app.use()为所有以/testinclude/test/1/或开头的路径触发/test/otherpath/more/1app.all()仅当它与请求的 url.x 完全匹配时才会触发

细节

匹配给定路由的所有路由处理程序或中间件都按照它们定义的顺序执行,app.all('*', fn)并且app.use(fn)在代码中的相同位置放置时没有任何不同的顺序。

在查看Express 代码时,app.all()它的工作方式似乎是通过本地安装的 HTTP 解析器支持的所有 HTTP 方法并为它们注册处理程序。因此,例如,如果您这样做:

app.all('*', fn);
Run Code Online (Sandbox Code Playgroud)

Express 代码将运行这些:

app.get('*', fn);
app.put('*', fn);
app.post('*', fn);
app.delete('*', fn);
// ...etc...
Run Code Online (Sandbox Code Playgroud)

app.use()方法独立。无论方法是什么,应用程序路由器的堆栈中都将只有一个处理程序被调用。因此,即使发出了一个不受支持的 http 动词并且解析器让请求达到这个程度,app.use()处理程序仍然会应用,而app.all()处理程序则不会。


如果您同时使用一个路径,app.all()app.use()这不仅仅是一个简单的通配符,比如'*',那么两者之间就会存在有意义的区别。

app.all(path, fn) 仅当请求的路径与此处的路径完全匹配时才会触发。

app.use(path, fn) 当请求路径的开头与此处的路径匹配时触发。

所以,如果你有:

app.all('/test', fn1);     // route 1
app.use('/test', fn2);     // route 2
Run Code Online (Sandbox Code Playgroud)

并且,您向以下请求发出请求:

http://yourhost.com/test         // both route1 and route2 will match
http://yourhost.com/test/1       // only route2 will match
Run Code Online (Sandbox Code Playgroud)

因为只有中间件app.use()会触发部分匹配,其中请求的 URL 包含超出此处指定的更多路径段。


因此,如果您打算插入一些为所有路由运行的中间件或为来自某个路径的所有路由运行的中间件,那么使用app.use(). 就我个人而言,我只会app.all(path, fn)在我希望处理程序仅针对特定路径运行时才使用,无论方法是什么,并且我不希望它也针对包含此路径的路径运行。我认为没有实际理由使用app.all('*', fn)over app.use(fn)