Javascript 从 express 中间件中排除路由

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27117337/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:44:22  来源:igfitidea点击:

Exclude route from express middleware

javascriptnode.jsexpresscoffeescriptmiddleware

提问by kreek

I have a node app sitting like a firewall/dispatcher in front of other micro services and it uses a middleware chain like below:

我有一个节点应用程序,就像其他微服务前面的防火墙/调度程序一样,它使用如下中间件链:

...
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
...

However for a particular GET route I want to skip all of them except rateLimiter and proxy. Is their a way to set a filter like a Rails before_filter using :except/:only?

但是,对于特定的 GET 路由,我想跳过除 rateLimiter 和代理之外的所有路由。他们是否可以使用 :except/:only 设置像 Rails before_filter 这样的过滤器?

回答by lukaszfiszer

Even though there is no build-in middleware filter system in expressjs, you can achieve this in at least two ways.

尽管 expressjs 中没有内置的中间件过滤系统,但您至少可以通过两种方式实现这一点。

First method is to mount all middlewares that you want to skip to a regular expression path than includes a negative lookup:

第一种方法是安装所有要跳过的中间件,而不是包含否定查找的正则表达式路径:

// 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);

Second method, probably more readable and cleaner one, is to wrap your middleware with a small helper function:

第二种方法,可能更易读和更清晰,是用一个小的辅助函数包装你的中间件:

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);

If you need more powerfull route matching than simple path === req.pathyou can use path-to-regexp modulethat is used internally by Express.

如果您需要比简单更强大的路由匹配,path === req.path您可以使用Express 内部使用的path-to-regexp 模块

UPDATE :- In express 4.17req.pathreturns only '/', so use req.baseUrl:

更新:-express 4.17req.path只返回'/',所以使用req.baseUrl

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

回答by Geelie

Built upon the answer from @lukaszfiszer as I wanted more than one route excluded. You can add as many as you want here.

建立在@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"));

Can't add as comment sorry.

无法添加为评论抱歉。

回答by kj007

You can also skip route like this by putting a condition on req.originalUrl:

您还可以通过在 req.originalUrl 上设置条件来跳过这样的路由:

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

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

回答by Guillaume

I use this regular expression with success : /^\/(?!path1|pathn).*$/.

我用这个正则表达式成功:/^\/(?!path1|pathn).*$/

回答by Guillaume Huard Hughes

You can define some routes like below.

您可以定义一些路由,如下所示。

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

    //A personal middleware
    //code

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

回答by riscarrott

Here's an example of using path-to-regexpas @lukaszfiszer's answer suggests:

这是使用path-to-regexp@lukaszfiszer's answer建议的示例:

import { RequestHandler } from 'express';
import pathToRegexp from 'path-to-regexp';

const unless = (
  paths: pathToRegexp.Path,
  middleware: RequestHandler
): RequestHandler => {
  const regex = pathToRegexp(paths);
  return (req, res, next) =>
    regex.exec(req.url) ? next() : middleware(req, res, next);
};

export default unless;

回答by Saikat Das

The way I achieved this is by setting up a middleware for a specific path like so

我实现这一点的方法是为特定路径设置中间件,如下所示

app.use("/routeNeedingAllMiddleware", middleware1);
app.use("/routeNeedingAllMiddleware", middleware2);
app.use("/routeNeedingAllMiddleware", middleware3);
app.use("/routeNeedingAllMiddleware", middleware4);

and then setting up my routes like so

然后像这样设置我的路线

app.post("/routeNeedingAllMiddleware/route1", route1Handler);
app.post("/routeNeedingAllMiddleware/route2", route2Handler);

For the other special route that doesn't need all the middleware, we setup another route like so

对于不需要所有中间件的其他特殊路由,我们设置另一条路由,如下所示

app.use("/routeNeedingSomeMiddleware", middleware2);
app.use("/routeNeedingSomeMiddleware", middleware4);

and then setting up the corresponding route like so

然后像这样设置相应的路线

app.post("/routeNeedingSomeMiddleware/specialRoute", specialRouteHandler);

The Express documentation for this is available here

在此处获得有关此的 Express 文档

回答by Ashley Davis

There's a lot of good answers here. I needed a slightly different answer though.

这里有很多很好的答案。不过,我需要一个稍微不同的答案。

I wanted to be able to exclude middleware from all HTTP PUT requests. So I created a more general version of the unlessfunction that allows a predicate to be passed in:

我希望能够从所有 HTTP PUT 请求中排除中间件。所以我创建了一个更通用的unless函数版本,允许传入一个谓词:

function unless(pred, middleware) {
    return (req, res, next) => {
        if (pred(req)) {
            next(); // Skip this middleware.
        }
        else {
            middleware(req, res, next); // Allow this middleware.
        }
    }
}

Example usage:

用法示例:

app.use(unless(req => req.method === "PUT", bodyParser.json()));