1. 程式人生 > >koa-router 路由引數與前端路由的結合

koa-router 路由引數與前端路由的結合

<

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 = `user id is:${userId}`;
});

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 = `user id is:${userId}`;
});

app.use(router.routes()).use(router.allowedMethods());

app.listen(3000);

console.log("server started at http:localhost:3000");

此時訪問以下連線進行測試,

  • http://localhost:3000/user/1
  • http://localhost:3000/user/2/foo
  • http://localhost:3000/user/3/foo/bar

均能正確命中頁面併成功獲取到路由中的引數。

正則路由及路由引數的獲取