28

假设我的 Express 应用程序中有一些 GET 路由:

// music albums
app.get('/api/albums', routes.albums.getAlbums);
app.get('/api/albums/:id', routes.albums.getAlbum);
app.get('/api/albums/artwork', routes.albums.getAlbumArtwork);

我尝试使用以下 jQuery AJAX 片段来攻击它们:

$("#retrieveAlbumArtwork").on("click", function() {
    $.ajax({
        url: "api/albums/artwork",
        type: "GET",
        data: {
            artist: $("#albumArtist").val(),
            title: $("#albumTitle").val()
        },
        // ... callbacks and such

出于某种原因,此调用使用/:id参数而不是显式/artwork路由命中第二个处理程序。像这样交换它们会使它们按预期运行:

// music albums
app.get('/api/albums', routes.albums.getAlbums);
app.get('/api/albums/artwork', routes.albums.getAlbumArtwork);
app.get('/api/albums/:id', routes.albums.getAlbum);

有人可以准确解释为什么会这样吗?我会假设 Express 足够聪明,可以识别 id 参数 ( /albums/23453243) 与查询字符串 ( /albums/artwork?artist=artistName&title=albumTitle) 并适当地路由,但情况似乎并非如此?

4

1 回答 1

25

不,不是。:id将匹配任何东西。所以/api/albums/artwork对于那场比赛是完全有效的。Express 也支持 RegExp 匹配。因此,您可以使用 RegExp 进行显式数字匹配路由。

另一种选择是app.param按照此处 API 文档中的说明使用:https ://expressjs.com/en/api.html#app.param

这允许您为路由器定义匹配的参数,这样您就可以拥有一个 URL,例如/api/albums/:albumIdwhere:albumId必须是数字,albumId如果您愿意,也可以在此时验证一个。

但总的来说,第二种方式你做的很正常,通常我把静态路由放在顶部,然后是动态路由,全部捕获,然后是错误处理程序。

于 2013-07-18T23:41:14.023 回答