拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Sails 框架 sails.getRouteFor() 深度指南:反向查询显式路由的方法与 URL

后端【免费下载链接】sailsRealtime MVC Framework for Node.js项目地址https://gitcode.com/gh_mirrors/sa/sails点击查看免费下载导读sails.getRouteFor()是 Sails 应用级 API 提供的路由反向查询方法给定一个路由目标route target例如MeController.login它会在应用显式配置的路由表中查找第一条指向该目标的记录并返回一个包含 HTTP 方法与 URL 的字典。本文以官方参考文档 docs/reference/application/advanced-usage/sails.getRouteFor.md 为主体结合源码 lib/app/get-route-for.js、lib/router/index.js 与单元测试 test/unit/app.getRouteFor.test.js系统讲解它的调用方式、返回结构、支持的目标语法、错误处理与典型实战场景如在视图模板中动态生成表单action与method并对比只返回 URL 的sails.getUrlFor()。一、API 概览sails.getRouteFor()的定位是把路由目标反查为地址。在 Sails 的显式路由配置中地址route address如post /auth/login与目标route target如MeController.login是成对出现的该 API 提供的是反向查询能力——传入目标拿到地址拆分出的 method 与 url。1.1 方法签名sails.getRouteFor(target);参数类型说明1target((string))路由目标字符串例如MeController.login1.2 返回值类型((dictionary)){ method: post, url: /auth/login }返回值字典包含两个字段methodHTTP 方法小写字符串例如get、post、put、delete、patch、options等如果目标指向的是一个不带动词前缀的通配地址则为空字符串见下文实现细节。url路由地址中的路径部分例如/auth/login、/wolves/:id、/*。二、基础用法与典型示例2.1 在控制器 action 中使用官方文档给出的经典场景是在控制器 action 中把路由信息作为模板局部变量locals传给视图// api/controllers/some-controller.js module.exports { someAction: function (req, res) { return res.view(pages/some-page-with-a-form-on-it, { formEndpoint: sails.getRouteFor(SomeotherController.someAction), // ... }); } };2.2 在视图模板中动态生成表单随后在 EJS 视图中即可直接用返回字典的url与method渲染表单的action与method属性form action%formEndpoint.url% method%formEndpoint.method% !-- ... -- /form这种反向查询 模板注入的组合非常实用当路由地址发生调整时只要目标target不变视图中的表单端点就会自动跟随更新避免了在控制器和模板里硬编码 URL 的维护成本。三、支持的目标语法target 的多种写法从单元测试 test/unit/app.getRouteFor.test.js 与路由解析源码 lib/router/index.js#L390-L489 可以看出target参数远不止文档示例中的Controller.action字符串一种形态。底层通过sails.router.getActionIdentityForTarget()将各种写法统一归一化为小写的 action identity形如user/find因此以下写法均能命中同一路由写法示例说明经典字符串WolfController.find控制器/action 字符串源码会去掉Controller后缀并把.替换为/新式 action 路径字符串user/signup、machines/machinefn斜杠分隔的 action 路径会转为小写 identity省略点/斜杠的字符串index无点无斜杠的字符串也能匹配测试中index命中get /home{ target: ... }包装{ target: PageController.signup }先解包target属性再解析字典写法{ controller: WolfController, action: create }拼接为wolf/create若指定了controller而未给action会抛错小写/简化控制器名{ controller: wolf, action: find }controller中的Controller后缀会被去除{ action: ... }写法{ action: machines/machinefn }直接以action属性作为 identity数组目标[{ policy: be-good }, { action: trouble/cause }]在数组中查找第一个含action的成员并递归解析关键行为大小写不敏感WolfController.CreaTe与{ controller: WOLF, action: finD }都能正确命中因为最终 identity 会被toLowerCase()归一化lib/router/index.js#L488。数组目标取第一个 action当目标是一组中间件/策略/action 的数组时getRouteFor会定位其中包含action的那一项lib/router/index.js#L469-L481测试中trouble/cause命中get /cause-trouble、trouble/cause-more命中put /cause-more-trouble即为此场景。四、底层实现原理getRouteFor的核心实现位于 lib/app/get-route-for.js其查找流程如下解析查询目标调用sails.router.getActionIdentityForTarget(routeQuery)把入参归一化为 action identity若入参不是合法的字符串/字典/数组目标则抛出code E_USAGE的使用错误。遍历显式路由遍历sails.router.explicitRoutes的所有键即路由地址对每个地址对应的 target 再次调用getActionIdentityForTarget求出其 identity与查询目标比对。这里有一个关键细节——只有能解析出 action identity 的目标才会参与比对视图目标如{ view: somepage }、原始 req/res 函数等其他目标会抛出E_NOT_ACTION_TARGET在查找中被当作不匹配跳过lib/app/get-route-for.js#L54-L65。取第一个匹配因为_.find按explicitRoutes键的插入顺序遍历所以第一个匹配就是配置文件中靠前的那条路由测试should return the _first_ matching route验证了这一点。找不到则抛错若无匹配抛出code E_NOT_FOUND的错误错误消息形如Route not found: No explicit route could be found in this app with the specified target (...)。规范化地址并解析 verb匹配到的地址若为*会按绑定时的行为规范化为/*lib/app/get-route-for.js#L80随后用detectVerb()lib/util/detect-verb.js从地址中提取 HTTP 动词与路径——它支持all|get|post|put|delete|trace|options|connect|patch|head前缀若地址没有动词前缀如/、/*verb为空字符串。关于显式路由的界定sails.router.explicitRoutes直接指向sails.config.routeslib/router/index.js#L103也就是说只有手动配置在config/routes.js或通过sails.config.routes注入里的路由才会被检索。因此该 API 严格限定的适用范围是显式路由详见下文注意事项。五、错误处理错误code触发条件处理建议E_NOT_FOUND在显式路由中找不到指定 target用try/catch捕获后读取err.code判断向用户返回友好提示或回退到默认端点E_USAGE入参不是合法的路由目标如getRouteFor()空调用、传入数字、普通对象{x:32, y:49}、函数等检查调用处的 target 是否书写正确源码中的错误消息会给出合法写法提示如{target: DuckController.quack}或{controller: duck, action: quack}典型捕获写法let route; try { route sails.getRouteFor(UserController.signup); } catch (err) { if (err.code E_NOT_FOUND) { // 目标在显式路由中不存在例如它是蓝皮书blueprint隐式路由 route { method: post, url: /signup }; // 自行回退 } else if (err.code E_USAGE) { throw new Error(sails.getRouteFor() 收到了非法的 route target); } }六、注意事项与边界官方文档docs/reference/application/advanced-usage/sails.getRouteFor.md与源码注释共同明确了以下边界只检索显式路由该函数搜索的是应用显式配置的路由即 sails.config.routes 中的内容由 hooks包括 蓝皮书路由绑定的隐式/影子路由不会被匹配。找不到目标会抛E_NOT_FOUND捕获错误后检查其code属性即可确认是否为E_NOT_FOUND。多个匹配时返回第一个以explicitRoutes中的配置顺序为准。只差一个 URL 时优先用sails.getUrlFor()如果只需要路由的 URL比如在视图中用作href直接用sails.getUrlFor()更简洁。从源码 lib/app/get-url-for.js#L31-L38 可以看出getUrlFor内部就是return sails.getRouteFor(routeQuery).url;即getRouteFor的一个轻量封装。七、实战小结sails.getRouteFor()为配置驱动的 Sails 应用提供了一条从 target 反查 method/url 的官方通道最适合以下场景视图渲染把表单端点、分页链接、AJAX 请求地址注入模板局部变量避免硬编码服务端跳转/校验在控制器中根据逻辑分支动态决定要重定向或请求的端点路由测试与断言在测试中验证某个 action 是否被显式路由到预期的 method 与 url单元测试 test/unit/app.getRouteFor.test.js 提供了完整的断言范式可在此基础上扩展自己的路由测试。使用时的三条准则是target 写法灵活但入参必须合法否则抛E_USAGE、只查显式路由蓝皮书等影子路由请自行回退、多个匹配取第一个路由顺序即优先级。赞分享后端【免费下载链接】sailsRealtime MVC Framework for Node.js项目地址https://gitcode.com/gh_mirrors/sa/sails点击查看免费下载相关推荐Sails v0.12 升级指南从 v0.11.x 迁移 Socket 方法、Waterline 与反向路由Sails v0.12 升级指南从 v0.11.x 迁移 Socket 方法、Waterline 与反向路由 Sails v0.12 是一次以 Socket.后端Sails 框架中 Waterline 查询实例的 .toPromise() 方法原理、用法与最佳实践Sails 框架中 Waterline 查询实例的 .toPromise 方法原理、用法与最佳实践 导读 .toPromise 是 Sails基于 Node后端Sails 模型Models深度指南从定义、查询到自定义方法Sails 模型Models深度指南从定义、查询到自定义方法 导读 本文聚焦 SailsRealtime MVC Framework for Node.后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门