Express服务器中间件执行两次



尝试在索引文件上记录一些数据后。我发现我的快递服务器执行了两次。为什么我会出现这个错误/bug?

截至本文发布之日,正在运行Node 12.13.0 LTS、Express 4.17.1和最新软件包版本。我尝试过对代码的某些部分进行注释,结果似乎总是运行两次。

我的app.js代码:

const express = require('express');
const expressLayouts = require('express-ejs-layouts');
const path = require('path');
const bodyParser = require('body-parser');
const favicon = require('serve-favicon');
const app = express();
// ENV Variables
require('dotenv').config();
const PORT = process.env.PORT;
// Authentication Packages
const session = require('express-session');
const passport = require('passport');
// Middlewares
app.use(favicon(path.join(__dirname,'public','images','favicon.ico')));
app.use(bodyParser.urlencoded({extended: false}));
app.use(express.json());
app.use(session({
secret: 'GBR6N7^?5Xx-Ldqxf&*-Hv$',
resave: false,
saveUninitialized: false,
//cookie: { secure: true }
}));
app.use(passport.initialize());
app.use(passport.session());
// View Engine
app.use(expressLayouts);
app.use(express.static(path.join(__dirname, 'public')));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// Routes
app.use('/', require('./routes/index'));
// Controllers
app.use('/profile', require('./routes/profile'));
app.use('/products', require('./routes/products'));
app.use('/bookmarks', require('./routes/bookmarks'));
// Catch 404
app.use((req, res) => {
res.render('pages/404');
});
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));

和我的index.js代码:

const express = require('express');
const router = express.Router();
// Official pages
router.get('/', (req, res) => {
// THIS IS THE CODE I GET TWICE ON CONSOLE
console.log(req.user);
console.log(req.isAuthenticated());
// THIS IS THE CODE I GET TWICE ON CONSOLE
res.render('pages/index');
});
router.get('/about', (req, res) => {
res.render('pages/about');
});
router.get('/features', (req, res) => {
res.render('pages/features');
});
// Footer pages
router.get('/terms', (req, res) => {
res.render('pages/terms');
});
router.get('/refunds', (req, res) => {
res.render('pages/refunds');
});
module.exports = router;

此外,我的profile.js(对于passport.js(上还有这两个函数:

passport.serializeUser((userId, done) => {
done(null, userId);
});
passport.deserializeUser((userId, done) => {
done(null, userId);
});

我得到两次结果:

console.log(req.user);
console.log(req.isAuthenticated());

输出(执行两次!(:

undefined
false
undefined
false

我期待一个:

undefined
false

由于Express路由的工作方式,路径/将与//about/favicon.ico等匹配。这是因为Express不仅支持端点路由,还支持路径装载。换句话说,express支持这样的东西:

const app = express();
const route = express.Router();
route.get('/world', (req, res) => { res.send('hello') });
app.get('/hello', route); // mounts world to hello 
// so we can access /hello/world

为了支持上述特性,express需要将路径(如/hello(解释为同时表示/hello/hello/anything/else。它需要将其视为端点,并且可能只是通往端点的路径。

这意味着,如果你有一条路径:

app.get('/', () => {});

如果浏览器请求/favicon.ico,它也将触发。浏览器请求favicon.ico在浏览器选项卡中绘制小图标。这就是为什么您的路由被触发两次的原因。

在编写Express路由/控制器时需要记住的几件事:

  1. 确保/路径是最后一个,否则它也会响应对所有其他路径的请求。

  2. 如果您正在使用express.static(),请确保它是在/路径之前设置的。是的,上面的第一条规则也应该涵盖这一点,但我经常看到这个问题,它有自己的观点。

在您的情况下,只需创建一个favicon.ico图标并将其保存在静态(公共(文件夹中,就可以解决此问题。

最新更新