9

我正在查看源代码,以了解它如何将命名路由参数映射到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.jspathRegexp()中定义的方法。方法定义如下:

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它以这种方式对路径名的匹配部分进行分组:

slash     the / symbol                                                                                                                    

format   I don't know what is the purpose of this one, explanation needed.                                    

key       the word (ie. \w+) after the : symbol                                                                           

capture a regex written in front of the key. Should be wrapped in parenthesis (ex. (.\\d+))

optional the ? symbol after the key                                                                                            

star       the * symbol                                                                                                                     

并且回调处理程序从上面的组构建一个正则表达式。


现在的问题是,这里的目的是什么format

我的理解根据以下几行:

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

并且提到的正则表达式是,

如果您.在组之后放置一个符号slash并且没有指定匹配条件(在括号中包裹的正则表达式key),则生成的正则表达式匹配其余部分,path直到它到达一个./符号。

那么有什么意义呢?


我问这个,因为:

  1. 我想在我的应用程序中提取和使用这个方法,并想在使用它之前完全了解它是如何工作的。
  2. 我在express.js文档中没有找到任何关于它的内容。
  3. 我只是好奇 :)
4

1 回答 1

5

它用于正确匹配文件扩展名等。

给定 path '/path/:file.:ext',考虑表达式之间的差异:

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

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

在第一种情况下,您最终得到的参数为

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

但如果没有格式检查,你最终会得到这个:

{
    file: 'f',
    ext: 'ile.js'
}
于 2013-03-10T01:22:47.927 回答