Express应用中get函数遇错时跳转至指定中间件(含404页)的方法
嘿,我来帮你搞定这两个Express的问题,结合你的代码示例来讲会更清楚:
问题1:在Express应用的get()函数中遇到错误时,如何跳转至下一个中间件(错误处理中间件)?
在Express里,要触发错误处理流程非常简单——当你在路由处理函数中遇到错误时,调用next()并传入一个错误对象即可。Express会自动跳过后续的普通中间件和路由,直接匹配到带有4个参数(err, req, res, next)的错误处理中间件。
结合你的代码,我们可以这样修改:
app.get('/events/*', function(req, res, next){ // 简化slice写法,省略第二个参数默认到字符串末尾 var text = req.originalUrl.slice(8); const queriedEvent = obj[text]; // 当查询的事件不存在时,创建错误并传入next if (!queriedEvent) { const err = new Error("请求的事件不存在"); err.statusCode = 404; // 自定义状态码,方便后续处理 return next(err); // 跳转至错误处理中间件 } app.locals.queried_event = queriedEvent; res.render("events"); });
接下来你需要在所有路由的最后定义一个全局错误处理中间件(必须是4个参数的函数,Express才会识别它为错误处理中间件):
app.use(function(err, req, res, next) { // 兜底处理,默认500状态码和通用错误信息 const statusCode = err.statusCode || 500; const errorMessage = err.message || "服务器内部错误"; // 根据状态码渲染对应页面,比如404就渲染404页面 if (statusCode === 404) { return res.status(404).render("404"); } res.status(statusCode).render("error", { message: errorMessage }); });
问题2:如何使用next()或其他技术仅跳转至指定的下一个中间件(即我的404页面)?
这里提供两种最常用的方案,你可以根据需求选择:
方案一:利用中间件执行顺序,让全局404中间件承接请求
把你的404页面中间件放在所有路由和普通中间件的最后,这样当你在路由里调用不带参数的next()时,请求就会流转到这个404中间件:
// 你的/events/*路由 app.get('/events/*', function(req, res, next){ var text = req.originalUrl.slice(8); const queriedEvent = obj[text]; if (!queriedEvent) { return next(); // 不传入错误,直接跳转到下一个中间件(即404) } app.locals.queried_event = queriedEvent; res.render("events"); }); // 全局404中间件,放在所有路由之后 app.use(function(req, res) { res.status(404).render("404"); });
这种方案的优势是统一处理所有404场景——不管是路由没匹配到,还是业务逻辑里的资源不存在,都会走到这个中间件。
方案二:抽离404处理函数,直接调用(更灵活)
如果你想直接指定跳转到404处理逻辑,可以把404的渲染逻辑抽成单独的函数,在需要的时候直接调用:
// 抽离404处理函数 function render404(req, res) { res.status(404).render("404"); } // 你的/events/*路由 app.get('/events/*', function(req, res){ var text = req.originalUrl.slice(8); const queriedEvent = obj[text]; if (!queriedEvent) { return render404(req, res); // 直接调用404处理函数 } app.locals.queried_event = queriedEvent; res.render("events"); }); // 同时保留全局404中间件,处理其他未匹配的路由 app.use(render404);
另外,如果你想用next()传递标识的方式实现,也可以这么做(不过不如前两种直观):
app.get('/events/*', function(req, res, next){ var text = req.originalUrl.slice(8); const queriedEvent = obj[text]; if (!queriedEvent) { return next("404"); // 传入自定义标识 } app.locals.queried_event = queriedEvent; res.render("events"); }); // 中间件中判断标识 app.use(function(identifier, req, res, next) { if (identifier === "404") { return res.status(404).render("404"); } // 处理其他标识或错误 next(identifier); });
内容的提问来源于stack exchange,提问作者Saif
相关产品推荐
相关产品推荐

