我从express.js开始,我想知道为什么下面的代码:
const express = require('express');
const app = express();
app.use('/', (req, res, next) => {
console.log('First middleware');
next();
});
app.use('/add-product', (req, res, next) => {
console.log('Second middleware');
res.send('<h1>The add-product page!</h1>');
});
app.use('/', (req, res, next) => {
console.log('Third middleware');
res.send('<h1>Hello from Express!</h1>');
});
app.listen(3000);
..当从chrome / firefox等中用localhost:3000/add-product
调用时,会产生
First middleware
Second middleware
First middleware
Third middleware
在控制台中?
答案 0 :(得分:1)
最后两个日志-First
和Third
用于favicon.ico
请求。当您在/add-product
返回html字符串时,浏览器会自动发出类似GET favicon.ico
的请求。
如果要阻止它,请在第二个中间件处返回html字符串,例如:
res.send('<head><link rel="icon" href="data:,"></head><h1>The add-product page!</h1>');
答案 1 :(得分:1)
您的浏览器正在进行两个网络调用:一个到/add-product
,另一个到/favicon.ico
。通过检查浏览器开发工具的“网络活动”标签来验证这一点,和/或从命令行(使用wget或类似工具)发出相同的请求,然后看看会发生什么。
第一个请求通过您的第一个和第二个中间件功能,第二个请求通过您的第一个和第三个中间件功能。
答案 2 :(得分:1)
首先,浏览器向您的服务器发出两个请求:
/add-product
/favicon.ico
然后,要了解路由,您必须了解app.use()
和app.get()
之间的路由匹配差异。
app.get()
仅在路由定义匹配整个请求的URL 时匹配。对于app.post()
,app.put()
,app.delete()
和app.all()
也是如此。
app.use()
匹配。
还请注意,app.get()
仅匹配GET请求,而app.use()
匹配任何HTTP动词(包括POST,PUT,DELETE),尽管在此特定示例中,此区别无关紧要,因为这两个请求均在此处发生是GET请求。
实际上,app.use()
和app.all()
(都与任何HTTP动词匹配)之间的区别是app.all()
需要完全匹配,而app.use()
仅接受部分匹配
此外,还会按照您的代码中指定的顺序检查路由是否匹配。
/添加产品路线
因此,当浏览器请求/add-product
时,您会得到以下提示:
app.use('/', ...)
之所以匹配,是因为/
是/add-product
的部分匹配。
app.use('/add-product', ...)
之所以匹配,是因为/add-product
与/add-product
的匹配项
然后,/add-product
路由发送响应并且不调用next()
,因此已为该请求完成了路由,并且根本没有检查第三条路由。
/favicon.ico路由
然后,当浏览器请求/favicon.ico
时,您会得到以下提示:
app.use('/', ...)
之所以匹配,是因为/
是/favicon.ico
的部分匹配。
app.use('/add-product', ...)
不匹配,因为它至少不是/favicon.ico
的部分匹配
然后,这次它检查您的第三条路由,并且它是app.use('/', ...)
的部分匹配项,它发送了一个响应并且没有调用next()
,因此已为该请求完成了路由。
注意:正确选择app.get()
或app.use()
很重要。