Исключить маршрут из Express middleware

У меня есть приложение узла, сидящее как брандмауэр / диспетчер перед другими микро-службами, и оно использует цепочку промежуточного программного обеспечения, как показано ниже:

...
app.use app_lookup
app.use timestamp_validator
app.use request_body
app.use checksum_validator
app.use rateLimiter
app.use whitelist
app.use proxy
...

однако для конкретного маршрута GET я хочу пропустить все из них, кроме rateLimiter и proxy. Является ли их способ установить фильтр как Rails before_filter, используя :except/: only?

5 ответов


хотя в expressjs нет встроенной системы фильтров промежуточного программного обеспечения, вы можете достичь этого по крайней мере двумя способами.

Первый метод заключается в монтировании всех промежуточных программ, которые вы хотите пропустить в путь регулярного выражения, чем включает отрицательный поиск:

// Skip all middleware except rateLimiter and proxy when route is /example_route
app.use(/\/((?!example_route).)*/, app_lookup);
app.use(/\/((?!example_route).)*/, timestamp_validator);
app.use(/\/((?!example_route).)*/, request_body);
app.use(/\/((?!example_route).)*/, checksum_validator);
app.use(rateLimiter);
app.use(/\/((?!example_route).)*/, whitelist);
app.use(proxy);

Второй метод, вероятно, более читаемый и чистый, заключается в том, чтобы обернуть промежуточное ПО с небольшой вспомогательной функцией:

var unless = function(path, middleware) {
    return function(req, res, next) {
        if (path === req.path) {
            return next();
        } else {
            return middleware(req, res, next);
        }
    };
};

app.use(unless('/example_route', app_lookup));
app.use(unless('/example_route', timestamp_validator));
app.use(unless('/example_route', request_body));
app.use(unless('/example_route', checksum_validator));
app.use(rateLimiter);
app.use(unless('/example_route', whitelist));
app.use(proxy);

Если вам нужно более мощное соответствие маршрута, чем просто path === req.path вы можете использовать модуль path-to-regexp который используется внутренне Express.


вы также можете пропустить маршрут, как это, поставив условие на req.originalUrl:

app.use(function (req, res, next) {

    if (req.originalUrl === '/api/login') {
    return next();
    } else {
         //DO SOMETHING
    }

Я использую это регулярное выражение с успехом : /^\/(?!path1|pathn).*$/.


вы можете определить маршруты, как показано ниже.

 app.use(/\/((?!route1|route2).)*/, (req, res, next) => {

    //A personal middleware
    //code

    next();//Will call the app.get(), app.post() or other
 });

построенный на ответе от @lukaszfiszer, поскольку я хотел исключить более одного маршрута. Вы можете добавить столько, сколько хотите здесь.

var unless = function(middleware, ...paths) {
  return function(req, res, next) {
    const pathCheck = paths.some(path => path === req.path);
    pathCheck ? next() : middleware(req, res, next);
  };
};

app.use(unless(redirectPage, "/user/login", "/user/register"));

Не могу добавить как комментарий извините.