摘要:問題描述在使用作為路由遇到了一個優先級問題如下代碼在訪問時路由會優先匹配到路由返回這個問題就很尷尬了項目空閑下來去翻看源碼終于找到了原因問題原因的源碼并不長和兩個文件加起來共一千多行代碼建議可以結合這篇文章閱讀其中造成這個問題的原因
問題描述
在使用Koa-router作為路由遇到了一個優先級問題.如下代碼
// routerPage.js file const router = require("koa-router") router.get("/test", ctx => { ctx.body = "test" }) router.get("/router/test", ctx => { ctx.body = "router test" }) module.exports = router // routerIndex.js file const router = require("koa-router") const routerPage = require("./routerPage") router.use(routerPage.routes(), routerPage.allowedMethods()) module.exports = router
在訪問"/router/test"時路由會優先匹配到"/test"路由,返回ctx.body = "test",這個問題就很尷尬了,項目空閑下來去翻看源碼終于找到了原因
問題原因Koa-router的源碼并不長,layer.js和router.js兩個文件加起來共一千多行代碼.建議可以結合這篇文章閱讀.
其中造成這個問題的原因就是router.js中router.use這個方法,方法源碼如下
// 主要作用: 給path添加中間件 Router.prototype.use = function () { var router = this; var middleware = Array.prototype.slice.call(arguments); var path = "(.*)"; // 如果path為array則遞歸調用use方法 if (Array.isArray(middleware[0]) && typeof middleware[0][0] === "string") { middleware[0].forEach(function (p) { router.use.apply(router, [p].concat(middleware.slice(1))); }); return this; } //如果傳入了path,則只對此path操作 var hasPath = typeof middleware[0] === "string"; if (hasPath) { path = middleware.shift(); } // 如果傳入參數為一個路由數組,則遍歷為每個路由添加前綴,中間件,并將此路由放入全局的路由數組 middleware.forEach(function (m) { if (m.router) { m.router.stack.forEach(function (nestedLayer) { if (path) nestedLayer.setPrefix(path); if (router.opts.prefix) nestedLayer.setPrefix(router.opts.prefix); router.stack.push(nestedLayer); }); if (router.params) { Object.keys(router.params).forEach(function (key) { m.router.param(key, router.params[key]); }); } } else { router.register(path, [], m, { end: false, ignoreCaptures: !hasPath }); } }); return this; };
問題就出在router.use(routerPage.routes(), routerPage.allowedMethods())時沒有設置前綴,
路由就自動添加了默認的前綴"(.*)",這里的path發生了改變,在路由后續的操作中,將path使用pathToRegExp轉換成正則表達式時"/test"這個path本應該是/^/test...../就會變成/(.*)//test...(大概是這個意思)
那么原本以/test開頭的路由就會匹配包含/test的路由
所以request path 為/router/test時會被/test路由先匹配中,路由也就不會往下匹配
將條件更精確的路由放到前面
在/test那個路由中加一個中間件,當匹配到/router/test時 await next()繼續向下執行
更改源碼Router.propertype.use 中 path = "(.*)" 為 path = false
在使用router.use時代碼做一定更改,代碼如下
// routerPage.js file const router = require("koa-router") router.get("test", ctx => { ctx.body = "test" }) router.get("router/test", ctx => { ctx.body = "router test" }) module.exports = router // routerIndex.js file const router = require("koa-router") const routerPage = require("./routerPage") router.use("/", routerPage.routes(), routerPage.allowedMethods()) module.exports = router
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/88300.html
路由koa-router——MVC 中重要的環節:Url 處理器 ?? iKcamp 制作團隊 原創作者:大哼、阿干、三三、小虎、胖子、小哈、DDU、可木、晃晃 文案校對:李益、大力萌、Au、DDU、小溪里、小哈 風采主播:可木、阿干、Au、DDU、小哈 視頻剪輯:小溪里 主站運營:給力xi、xty 教程主編:張利濤 視頻地址:https://www.cctalk.com/v/151...
摘要:本文首發于用控制路由在中長這樣還有上的框架兩者都用來控制路由,這樣寫的好處是更簡潔更優雅更清晰。反觀或上的路由完全差了一個檔次從開始就有了,只是瀏覽器和都還沒有支持。 本文首發于:用Decorator控制Koa路由 showImg(https://segmentfault.com/img/remote/1460000015348698); 在Spring中Controller長這樣 @...
摘要:第三篇,有關生態中比較重要的一個中間件第一篇源碼閱讀第二篇源碼閱讀與是什么首先,因為是一個管理中間件的平臺,而注冊一個中間件使用來執行。這里寫入的多個中間件都是針對該生效的。 第三篇,有關koa生態中比較重要的一個中間件:koa-router 第一篇:koa源碼閱讀-0 第二篇:koa源碼閱讀-1-koa與koa-compose koa-router是什么 首先,因為koa是一個管...
摘要:我們分別使用這樣的原則來測試向每個架構注入個靜態路由,測試最末尾的那個。而我們如何做到達到的性能,主要我們在內存中維護了一份靜態路由列表,能讓程序以最快的速度找到我們需要的。 對比 如果使用nodejs來搭建Service服務,那么我們首選express或者koa,而fastify告訴我們一個數據: Framework Version Router? Requests/sec ...
摘要:代碼結構執行流程上面兩張圖主要將的整體代碼結構和大概的執行流程畫了出來,畫的不夠具體。那下面主要講中的幾處的關鍵代碼解讀一下。全局的路由參數處理的中間件組成的對象。 代碼結構 showImg(https://segmentfault.com/img/remote/1460000007468236?w=1425&h=1772); 執行流程 showImg(https://segmentf...
閱讀 2219·2019-08-30 15:53
閱讀 2444·2019-08-30 12:54
閱讀 1187·2019-08-29 16:09
閱讀 718·2019-08-29 12:14
閱讀 746·2019-08-26 10:33
閱讀 2461·2019-08-23 18:36
閱讀 2950·2019-08-23 18:30
閱讀 2111·2019-08-22 17:09