javascript - 在单独的 js 文件中处理所有带有前缀的路由

标签 javascript node.js express

我的 express 应用程序中有多个路由用于不同的前缀。每个前缀的路由都在单独的文件中定义。

const routes = require('./server/routes');
app.use('/api', routes.apirouter);
app.use('/', routes.webrouter);

其中“./server/routes.js”是:

module.exports.apirouter = require('./api');
module.exports.webrouter = require('./webroutes');

因此,目前,我正在处理和定义所有在“api.js”中带有/api 前缀的路由,所有其他路由都在“webroutes.js”中定义

现在类似地,我需要将前缀为“fetch-”的所有路由定义到单独的 js 文件“fetch.js”,因此 http://localhost/fetch-onehttp://localhost/fetch-two需要在fetch.js

中定义

但是以下代码不适用于/fetch-one:

const routes = require('./server/routes');
app.use('/api', routes.apirouter);
app.use('/', routes.webrouter);
app.use('/fetch-*', routes.fetchrouter);

路由.js:

module.exports.apirouter = require('./api');
module.exports.webrouter = require('./webroutes');
module.exports.fetchrouter = require('./fetch');

获取.js: 在 fetch.js 中分别为/fetch-one 和/fetch-two 定义了路由

var fetchRouter = require('express').Router();
fetchRouter.get('/fetch-one', function(req, res, next) {
    // localhost/fetch-one not passed control here
});
fetchRouter.get('/fetch-two', function(req, res, next) {
    // localhost/fetch-two not passed control here
})
module.exports = fetchRouter;

最佳答案

问题是一旦你这样做了:

 app.use('/fetch-*', routes.fetchrouter);

然后,路径的 /fetch-* 部分已从 fetchrouter 的路由中删除。因此,当您执行以下操作时:

fetchRouter.get('/fetch-one', ...)

那将不匹配,因为 /fetch-one 已经从路由路径中删除。 URL 必须是 /fetch-xxx/fetch-one 才能匹配。

最简单的设计是更改您的路径,使 URL 为 /fetch/one/fetch/two,这更符合 Express 路由器的方式工作。然后你会去:

 app.use('/fetch', routes.fetchrouter);

并且,在该路由器中有路由

 app.get('/one, ...)
 app.get('/two, ...)

这是最简洁的 URL 设计,符合 Express 路由器最简单的工作方式。


如果您打算继续使用 /fetch-one URL 设计,那么另一个想法是让 fetchRouter 查看所有顶级 URL:

 app.use('/', fetchRouter);

然后让它只包含您希望它查看的顶级路由的路由。如果它不处理事情,Express 将继续寻找其他匹配的路由:

 app.get('/fetch-one', ...);
 app.get('/fetch-two', ...);

您需要确保没有接受所有请求的贪婪顶级路由器,并确保该路由器只接受它需要的请求,以便其他顶级路由有机会匹配。


如果你真的想为路由器保留 /fetch-* 设计,那么你可以做一些你自己的路由和 URL 比较:

 app.use('/fetch-*', routes.fetchrouter);

然后,在 fetchrouter 中:

 app.get("/", function(req, res, next) {
     switch(req.baseUrl) {
         case "/fetch-one":
             // process /fetch-one here
             break;
         case "/fetch-two":
             // process /fetch-two here
             break;
         default:
             next();
     }
 });

我想到了另一个使用 Express 参数的选项,您只需使用处理函数来获取路由而不是路由器:

 app.use('/fetch-:id', routes.fetchHandler);

然后,在 fetchHandler 中:

 function fetchHandler(req, res, next) {
     switch(req.params.id) {
         case "one":
             // process /fetch-one here
             break;
         case "two":
             // process /fetch-two here
             break;
         default:
             next();
     }
 });

除了大开关,你也可以让它成为表驱动,如果你有很多路由,这可能更干净:

 app.use('/fetch-:id', routes.fetchHandler);

然后,fetchHandler 将是一个导出函数:

 const routeTable = {
     one: routeOne,
     two: routeTwo,
     three: routeThree,
     ....
 };

 function fetchHandler(req, res, next) {
     let fn = routeTable[req.params.id];
     if (fn) {
         fn(req, res, next);
     } else {
         next();
     }
 });

 function routeOne(req, res, next) {
     ...
 }

 function routeTwo(req, res, next) {
     ...
 }

 function routeThree(req, res, next) {
     ...
 }

关于javascript - 在单独的 js 文件中处理所有带有前缀的路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58831355/

相关文章:

javascript - Angular 2 神秘地修改具有相同值的对象内的所有子嵌套相似对象

javascript - 基本 'if' 语句在 handlebars JS 中不起作用

javascript - Uncaught ReferenceError : say is not defined

javascript - NodeJS 中 POST 请求的请求正文为空

node.js - ExpressJS如何构建应用程序?

javascript - 如何通过函数向类提供选项列表?

JavaScript:if else 内的变量未定义

node.js - nodejs 在 redis 失败时终止

javascript - Visual Studio代码: Run node script on save

angularjs - Node 抛出 TypeError : Cannot read property 'indexOf' of undefined