javascript @koa/router的Router示例上的`use`方法是如何工作的?

mzaanser  于 2023-06-20  发布在  Java
关注(0)|答案(2)|浏览(134)

我有一个非常简单的路由代码,使用@koa/router

import Koa from 'koa';
import Router from '@koa/router';

const app = new Koa();

const router = new Router();

router.use('/api', (ctx, next) => {
  ctx.body = 'catch all with use';
  ctx.status = 201;
  next();
});

app.listen(3000);

然而,访问路径http://localhost:3000/api返回404。那么,use路由器的具体使用方法是什么呢?
我希望将所有以/api前缀开头的请求发送到自定义中间件,该中间件本身可以是@koa/router中间件或任何其他Koa中间件。

f4t66c6m

f4t66c6m1#

我设法匹配了/api/下的所有内容:

import Koa from 'koa';
import Router from '@koa/router';

const app = new Koa();
const apiRouter = new Router();

const catchAll = new Router();
catchAll.get('/(.*)', async (ctx, next) => {
    console.log("Here is some middleware");
    console.log('/' + ctx.params[0]);
    await next();
    console.log(ctx.body)
}, async (ctx, next) => {
    ctx.body = 'catch all with URL ' + ctx.url;
    ctx.status = 201;
    await next();
});

apiRouter.use('/api', catchAll.routes());
app.use(apiRouter.routes());
app.listen(3000);

但是,这与没有尾随斜杠的/api不匹配。
我找到了一个更简单的方法来实现同样的目标。但是,它不使用路由器示例的use方法:

import Koa from 'koa';
import Router from '@koa/router';

const app = new Koa();
const apiRouter = new Router();

apiRouter.get('/api/(.*)', async (ctx, next) => {
    console.log("Here is some middleware");
    console.log('/' + ctx.params[0]);
    await next();
    console.log(ctx.body)
}, async (ctx, next) => {
    ctx.body = 'catch all with URL ' + ctx.url;
    ctx.status = 201;
    await next();
});
app.use(apiRouter.routes());
app.listen(3000);

注意第二种方式的'/api/.*'是第一种方式的'/api' + '/(.*)'
显然,路由器示例的useget路径执行连接(类似地为post等),因此,如果您在上面的第一种方式中使用(.*)而不使用catchAll.get的前导斜杠,它将尝试将其连接到/api(.*),然后将匹配/api2等。

bjg7j2ky

bjg7j2ky2#

在您的示例中有两件事需要更新
1.我建议从Koa/router切换到使用前缀选项。那么您就不需要use中间件中的路径名

// this has `prefix` as an option now
const router = new Router({ prefix: '/api' });

router.use((ctx, next) => {
  ctx.body = 'catch all with use';
  ctx.status = 201;
  next();
});

1.您必须在应用程序中注册路由器。koa app不知道您示例中的apiRouter。你需要在app.listen之前添加这一行:

app.use(apiRouter.routes());

相关问题