Node.js中App.Get路由顺序异常导致网站崩溃问题求助
哈哈,这个问题我之前踩过一模一样的坑!本质就是Node.js常用的路由框架(比如Express)是按定义顺序从上到下匹配路由的,一旦某个路由规则匹配成功,就会直接执行对应的处理逻辑,不会再继续往下查找其他路由。你遇到的情况就是/:category/:subcategory这个动态路由规则太宽泛,把/api/65625499当成了category=api、subcategory=65625499来匹配,而这个路由的处理逻辑又没适配这种情况,才导致网站崩溃。
根据你说的“无法预先确定category”的情况,给你几个可行的解决方案:
1. 调整路由顺序(最优方案)
把更具体的路由放在动态路由前面。比如先定义/api/:id这个路由,再定义/:category/:subcategory。这样当请求/api/65625499过来时,会先匹配到/api/:id,而不会被后面的动态路由截胡。
示例代码:
// 先定义具体的API路由 app.get('/api/:id', (req, res) => { // 处理/api/:id的逻辑 }); // 再定义宽泛的动态路由 app.get('/:category/:subcategory', (req, res) => { // 处理分类子分类的逻辑 });
2. 给动态路由添加参数约束
如果因为某些原因不能调整路由顺序,可以给category参数添加正则表达式约束,让它不会匹配api这类特定字符串。
比如,让category不能是api:
app.get('/:category(?!api)/:subcategory', (req, res) => { // 处理逻辑 });
这里的(?!api)是负向前瞻正则,意思是“category不能是api”。
如果你的category只能是特定类型的字符串(比如只能是字母,不能包含数字),也可以更精准地约束:
// 只允许category是字母组成的字符串 app.get('/:category([a-zA-Z]+)/:subcategory', (req, res) => { // 处理逻辑 });
3. 在动态路由处理函数中做校验跳转
如果前两种方法都不适用,可以在/:category/:subcategory的处理函数开头,检查当前匹配的category是不是api(或者其他不应该被该路由处理的字符串),如果是的话,调用next()让请求继续往下匹配其他路由。
示例代码:
app.get('/:category/:subcategory', (req, res, next) => { // 如果category是api,交给后面的路由处理 if (req.params.category === 'api') { return next(); } // 正常处理分类和子分类的逻辑 // ... }); // 后面再定义/api/:id的路由 app.get('/api/:id', (req, res) => { // 处理API请求的逻辑 });
总结一下,最推荐的是第一种调整路由顺序的方法,符合路由框架的设计逻辑,也最简洁。后面两种方法是特殊场景下的备选方案。
内容的提问来源于stack exchange,提问作者Berkin

