koa-router 定制路由時支持通過冒號形式在 url 中指定參數,該參數會掛載到 context
上然后可通過 context.params.paramName
方便地獲取。
考察下面的示例:
var Koa = require("koa");
var Router = require("koa-router");
var app = new Koa();
var router = new Router();
router.get("/user/:id", async function(ctx, next) {
const userId = ctx.params.id;
ctx.body = </span>user id is:<span class="pl-s1"><span class="pl-pse">${</span>userId<span class="pl-pse">}</span></span><span class="pl-pds">
;
});
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000);
console.log("server started at http:localhost:3000");
啟動服務后可看到頁面中展示出了從 url 中獲取到的 id 參數。
路由參數的獲取展示
現在來考慮另一種情況,即路由中支持前端路由的情況。
即把現在的 url 由 /user/:id
的形式擴展成 /user/:id/foo/bar
,這里 /foo/bar
部分可以是任何路由,作為前端處理的路由部分。
為了實現這樣的前端路由部分,服務端路由的配置需要借助正則來進行,
- router.get("/user/:id", async function(ctx, next) {
+ router.get(["/user/:id", /\/user\/([\w|\d]+)\/.*/], async function(ctx, next) {
const userId = ctx.params.id;
ctx.body = `user id is:${userId}`;
});
這里將路由中 url 由單個字符串變成了數組形式,第一個還是原來的路由,這樣正常的通過 /user/1
形式過來的頁面能命中該路由。同時添加 /\/user\/([\w|\d]+)\/.*/
部分,因為正則情況下不再支持路由中通過冒號進行參數的配置,所以這里 /user/
后跟隨的 id 也需要使用正則來替換掉。
但正則匹配下的路由就不能通過 context.params
來訪問 url 上的參數了。不過好在可通過在正則中定義匹配組(Capturing Groups)的形式來定義參數,即其中 ([\w|\d]+)
括號包裹的部分,稱為一個匹配組,一個匹配組是會自動被掛載到 context.params
上的,只是不像通過冒號定義的參數那樣會有一個名字,這種形式的參數按照匹配到的順序形成一個數組賦值到 context.params
,所以訪問第一個匹配組形成的參數可通過 context.params[0]
來獲取。
於是上面的代碼稍加修正后,就能夠正確處理來自命名參數(通過冒號匹配)或正則參數形成的 query 參數了。
- router.get("/user/:id", async function(ctx, next) {
+ router.get(["/user/:id", /\/user\/([\w|\d]+)\/.*/], async function(ctx, next) {
- const userId = ctx.params.id;
+ const userId = ctx.params.id || ctx.params[0];
ctx.body = `user id is:${userId}`;
});
最后完整的代碼會是這樣:
var Koa = require("koa");
var Router = require("koa-router");
var app = new Koa();
var router = new Router();
router.get(["/user/:id", //user/([\w|\d]+)/.*/], async function(ctx, next) {
const userId = ctx.params.id || ctx.params[0];
ctx.body = </span>user id is:<span class="pl-s1"><span class="pl-pse">${</span>userId<span class="pl-pse">}</span></span><span class="pl-pds">
;
});
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000);
console.log("server started at http:localhost:3000");
此時訪問以下連接進行測試,
均能正確命中頁面並成功獲取到路由中的參數。
正則路由及路由參數的獲取