Express访问/create路由触发MongoDB ObjectId转换CastError问题
问题根因
路由匹配顺序错误,和app.js全局配置、数据库连接、缓存都没关系。
Express路由匹配规则是按代码注册顺序从上到下执行,先注册的路由优先级更高。你在routes/products.js中先注册了动态路由router.get('/subset/:id', ...),后注册固定路径路由router.get('/subset/create', ...)。访问/products/subset/create时,路径会先命中前面的动态路由规则,把字符串create当做:id参数传入products_subset_get控制器。该控制器内部会用这个参数查询MongoDB中ObjectId类型的关联字段,create不符合ObjectId必须是24位十六进制字符串的格式要求,就抛出了类型转换错误。/categories/create能正常访问,是因为你在categories路由文件里把固定路径/create写在了动态参数/:id前面,不会出现误匹配。
修复方案
二选一即可:
- 方案1(推荐,和现有categories路由的写法逻辑保持一致):调整
routes/products.js内的路由注册顺序,把所有固定路径的路由放在带动态参数的路由前面,修改后代码如下:
var express = require('express'); var product_controller = require('../controllers/productControllers'); var router = express.Router(); router.get('/', product_controller.products_listing_get); // 固定路径路由优先注册 router.get('/subset/create', product_controller.products_create_get); router.post('/subset/create', product_controller.products_create_post); router.get('/subset/update/:id', product_controller.products_update_get); router.put('/subset/update/:id', product_controller.products_update_post); // 动态参数路由后注册 router.get('/subset/:id', product_controller.products_subset_get); router.delete('/subset/:id', product_controller.products_delete_post); module.exports = router;
- 方案2:如果不想调整路由顺序,可以给动态参数
:id增加正则校验,只允许合法的ObjectId格式匹配该路由,把路由路径从/subset/:id改为/subset/:id([0-9a-fA-F]{24})即可,不符合格式的路径会自动跳过该路由继续向下匹配。
内容的提问来源于stack exchange,提问作者user3804227
相关产品推荐
相关产品推荐

