[英]express.js routes explanation
我正在查看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);
});
我意识到这个功能的核心是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行的正则表达式,/( /(\\/)?(\\.)?:(\\w+)(?:(\\(.*?\\)))?(\\?)?(\\*)?/g
( /(\\/)?(\\.)?:(\\w+)(?:(\\(.*?\\)))?(\\?)?(\\*)?/g
。 /(\\/)?(\\.)?:(\\w+)(?:(\\(.*?\\)))?(\\?)?(\\*)?/g
( /(\\/)?(\\.)?:(\\w+)(?:(\\(.*?\\)))?(\\?)?(\\*)?/g
以这种方式对路径名的匹配部分进行分组:
削减 /
符号
格式 我不知道这个的目的是什么,需要解释。
键字(即\\w+
后) :
符号
捕获 在key
前面写的正则表达式。 应该用括号括起来(例如(.\\\\d+)
)
可选 的?
key
后的符号
明星 *
符号
并且回调处理程序从上面的组构建一个正则表达式。
现在的问题是 , format
的目的是什么?
我的理解如下:
(format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)'))
和前面提到的正则表达式是,
如果你放一个.
在slash
组之后的符号并且没有指定匹配条件(正则表达式包含在key
后的括号中),生成的正则表达式匹配path
的其余部分,直到它到达a .
或/
符号。
那有什么意义呢?
我问这个,因为:
它适用于匹配文件扩展名等。
给定路径'/path/:file.:ext'
,考虑表达式之间的差异:
// With 'format' checking
/^\/path\/(?:([^\/]+?))(?:\.([^\/\.]+?))\/?$/
// Without 'format' checking
/^\/path\/(?:([^\/]+?))(?:([^\/]+?))\/?$/
在第一种情况下,你最终得到了params
{
file: 'file',
ext: 'js'
}
但没有格式检查,你最终得到这个:
{
file: 'f',
ext: 'ile.js'
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.