NodeJS-错误的Express路由被触发

时间:2019-04-02 16:47:14

标签: node.js rest api express routes

我有以下用于后端的路由...

admin.js

router.get('/contents', ...);  // GET /admin/contents

router.get('/:adminID', ...);  // GET /admin/[adminID]

router.put('/:adminID', ...);  // PUT /admin/[adminID]

router.get('/', ...);  // GET /admin

router.post('/', ...);  // POST /admin

..但是在测试中,以下内容:

PUT /admin/contents

触发PUT /admin/[adminID]路线。但是“内容”不是ID。我知道为什么会发生这种情况(即符合模式),但是我不确定什么是最佳/通用的解决方案?理想情况下,我希望它认识到“内容”不是ID,实际上只是试图使用不可用的端点。

我可以使用类似...

router.use('/contents', require('./admin-contents'));

但是我宁愿将每个顶级端点限制为一个文件,而不是将其分散到这么多文件中。

在最坏的情况下,它将查找ID为“ contents”的管理员,并返回“找不到管理员”,但是我更希望它返回404,因为对于{{1 }}。

编辑#1

为明确起见,/admin是字母和数字的组合,两者都出现在字符串的任何位置。正则表达式不起作用。

此外,adminID的唯一路由是/admin/contents。必须为所有其他方法(GETPUTPATCH等)实现空白路由也不理想。

2 个答案:

答案 0 :(得分:1)

为避免这种情况,您可以在路径中的参数项名称后提供regex

router.put('/:adminID(\\d+)', (req, res) => {
   console.log(req.params.adminID); // I'm a number
});

现在adminID必须是数字,否则它将不会输入路线。

虽然没有直接记录在express routing上,但由于express使用path-to-regexp,我们可以查看其相关文档:

它记录在Custom Matching Parameters

const regexpNumbers = pathToRegexp('/icon-:foo(\\d+).png')
// keys = [{ name: 'foo', ... }]

regexpNumbers.exec('/icon-123.png')
//=> ['/icon-123.png', '123']

regexpNumbers.exec('/icon-abc.png')
//=> null

更新

  

您建议仅检查一个已知长度的数字   字符串应该起作用,

app.put('/:adminID((?:\\w+(?<=\\d+)(?:\\w+)?))', (req, res) => {
   // I have at least 1 number
   // I can have or not alpha-numeric characters
   res.send(req.params.adminID);
});

正则表达式使用Postive lookbehind assertions,自Node.js 9.11.2起就被支持,没有任何标志。因此,如果您使用的是旧版本,请升级或使用--harmony标志运行它。

答案 1 :(得分:0)

您可以利用节点按顺序解释处理程序这一事实:

app.put('/admin/contents',  (req, res) => res.send('contents'))
app.put('/admin/:adminId',  (req, res) => res.send('id'))

当您输入admin/contents时,将返回内容,对于其他任何URL admin/whatever id 都将返回。