简体   繁体   English

Node Express-路由路径冒号参数异常

[英]Node Express - Route path colon parameter exception

Currently I have two routes in my app: 目前,我的应用中有两条路线:

/invoice/:invoice returns JSON data of an Invoice document from Mongoose /invoice/:invoice从Mongoose返回发票文档的JSON数据

/invoice/preview returns a preview of an invoice inside an HTML template (note that this doesn't always preview an existing invoice, it could also be a non-existing of which its data is supplied via url parameters, which is why the route cannot be /invoice/:invoice/preview ) /invoice/preview返回HTML模板中的发票预览(请注意,这并不总是预览现有的发票,也可能是不存在的,其数据是通过url参数提供的,这就是路由的原因不能为/invoice/:invoice/preview

Question

There should be a better way to declare these two specific routes, because the /invoice/preview route now calls both handlers, since it matches both regexes. 应该有一个更好的方法来声明这两个特定的路由,因为/invoice/preview路由现在调用两个处理程序,因为它匹配两个正则表达式。

If we were talking in CSS selectors /invoice/:invoice:not(preview) would be the behavior I want. 如果我们在CSS选择器中讨论/invoice/:invoice:not(preview)就是我想要的行为。 Unfortunately I don't find any documentation for this. 不幸的是,我没有找到任何文档。

Is there any way to achieve this or any way to improve this endpoint structure? 是否有任何方法可以实现此目标或改善端点结构?

Declare more specific routes first: 首先声明更具体的路线:

router.get('/invoice/preview', ...);

router.get('/invoice/:invoice', ...);

Express checks routes in order of declaration, so once it has matched a request against /invoice/preview (and provided that its handler sends back a response), the less-specific /invoice/:invoice won't be considered. Express按照声明的顺序检查路由,因此,一旦它与/invoice/preview匹配了一个请求(并提供了它的处理程序发送回一个响应),就不会考虑不太具体的/invoice/:invoice

Alternatively, if :invoice should always match a specific pattern (say a MongoDB ObjectId ), you can limit the route to requests matching that pattern: 或者,如果:invoice应该始终匹配特定的模式(例如MongoDB ObjectId ),则可以将路由限制为匹配该模式的请求:

router.get('/invoice/:invoice([a-fA-F0-9]{24})', ...);

That pattern doesn't match "preview" , so the order wouldn't matter so much in that case. 该模式与“ preview”不匹配,因此在这种情况下顺序无关紧要。

If this isn't possible, you could create a middleware that would check if req.params.invoice matches "preview" and, if so, would pass along the request further down the handler chain: 如果无法做到这一点,则可以创建一个中间件,该中间件将检查req.params.invoice匹配“ preview” ,如果是,则将请求沿处理程序链进一步传递:

let notIfPreview = (req, res, next) => {
  if (req.params.invoice === 'preview') return next('route');
  next();
};

router.get('/invoice/:invoice', notIfPreview, ...);
router.get('/invoice/preview', ...);

(documented here ) 在此处记录

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM