如何阻止Express匹配多个路由?根路径访问触发双路由问题
Express路由重复触发问题解决
问题说明
访问网站根路径时,两个路由都会收到请求:一个是正常的根路径请求,另一个是浏览器自动发送的favicon.ico请求,后者被/:pageId/路由匹配处理。将所有路由写在单个文件时无此问题,问题出在app.use()的路由挂载逻辑上。
代码示例
入口文件 index.js
const express = require('express') const app = express() const index = require('./backend/pages/index') const page = require('./backend/pages/page') app.use('/', index) app.use('/:pageId/', page) app.listen(3000, () => { console.log(`Listening on port ${3000}`) })
路由文件(index.js 和 page.js 内容一致)
const express = require('express'), router = express.Router() router.get('/', async (req, res) => { console.log(`got a request ${Math.random()}`) return res.send('something') }) module.exports = router
问题根源
浏览器访问页面时会自动发起GET /favicon.ico请求获取网站图标;而/:pageId/作为动态路由,其参数:pageId会匹配任意非空路径段,favicon.ico被识别为pageId的值,导致该路由处理了favicon请求。
解决办法
1. 给动态路由添加专属前缀
修改动态路由的挂载路径,增加特定前缀避免和根路径下的请求冲突:
// index.js 中修改动态路由挂载 app.use('/pages/:pageId/', page)
2. 直接拦截favicon请求
在所有路由注册前添加favicon的处理逻辑,阻止其进入后续路由匹配:
const express = require('express') const app = express() // 拦截favicon请求,返回204无内容状态 app.get('/favicon.ico', (req, res) => res.sendStatus(204)) const index = require('./backend/pages/index') const page = require('./backend/pages/page') app.use('/', index) app.use('/:pageId/', page) app.listen(3000, () => { console.log(`Listening on port ${3000}`) })
3. 对动态参数做格式校验
在动态路由中添加参数格式验证,只处理符合预期的pageId:
// page.js 路由中添加校验逻辑 router.get('/', async (req, res) => { // 示例:仅允许数字类型的pageId if (!/^\d+$/.test(req.params.pageId)) { return res.sendStatus(404) } console.log(`got a request ${Math.random()}`) return res.send('something') })
内容的提问来源于stack exchange,提问作者fatkutas
相关产品推荐
相关产品推荐

