express.js路由解释

我正在查看express.js源代码,以了解如何将命名的路由参数映射到req.params属性。

对于那些不知道的人,在express.js中,你可以用命名参数定义路由,使它们成为可选的,只允许具有特定格式(和更多)的路由:

 app.get("/user/:id/:name?/:age(\\d+)", function (req, res) { console.log("ID is", req.params.id); console.log("Name is", req.params.name || "not specified!"); console.log("Age is", req.params.age); }); 

我意识到这个function的核心是在lib / utils.js中定义的一个名为pathRegexp()的方法。 方法定义如下:

 function pathRegexp(path, keys, sensitive, strict) { if (path instanceof RegExp) return path; if (Array.isArray(path)) path = '(' + path.join('|') + ')'; path = path .concat(strict ? '' : '/?') .replace(/\/\(/g, '(?:/') .replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?(\*)?/g, function (_, slash, format, key, capture, optional, star) { keys.push({ name: key, optional: !! optional }); slash = slash || ''; return '' + (optional ? '' : slash) + '(?:' + (optional ? slash : '') + (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')' + (optional || '') + (star ? '(/*)?' : ''); }) .replace(/([\/.])/g, '\\$1') .replace(/\*/g, '(.*)'); return new RegExp('^' + path + '$', sensitive ? '' : 'i'); } 

重要的是第7行的正则expression式,/( /(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?(\*)?/g ( /(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?(\*)?/g ( /(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?(\*)?/g ( /(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?(\*)?/g ( /(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?(\*)?/g ( /(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?(\*)?/g这样分组path名的匹配部分:

斜杠 /符号

格式 我不知道这个是什么目的,需要说明。

:符号后 键入 单词(即。 \w+

捕获 写在key前面的正则expression式。 应该用括号括起来(例如(.\\d+)

可选 ? 符号后的key

星号 *符号

callback处理程序从上面的组中构build一个正则expression式。


现在问题是format的目的什么?

我根据以下的线理解:

 (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) 

和提到的正则expression式是,

如果你把一个. 符号在slash组之后,并且没有指定一个匹配条件(包含在括号后面的正则expression式),生成的正则expression式匹配path的其余部分,直到它到达一个./符号。

那么有什么意义呢?


我这样问,因为:

  1. 我想在我的应用程序中提取和使用这种方法,并希望在使用它之前完全理解它是如何工作的。
  2. 我没有find有关express.js文档的任何信息。
  3. 我只是好奇 :)

这是适当的匹配文件扩展名等。

给定path'/path/:file.:ext' ,考虑expression式之间的区别:

 // With 'format' checking /^\/path\/(?:([^\/]+?))(?:\.([^\/\.]+?))\/?$/ // Without 'format' checking /^\/path\/(?:([^\/]+?))(?:([^\/]+?))\/?$/ 

在第一种情况下,你最终会得到params

 { file: 'file', ext: 'js' } 

但没有格式检查,你最终这样做:

 { file: 'f', ext: 'ile.js' }