Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/42.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 从express中间件中排除路由_Javascript_Node.js_Express_Coffeescript_Middleware - Fatal编程技术网

Javascript 从express中间件中排除路由

Javascript 从express中间件中排除路由,javascript,node.js,express,coffeescript,middleware,Javascript,Node.js,Express,Coffeescript,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路径,我想跳过除RateLimitor和proxy之外的所有路径。使用:exce

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

...
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路径,我想跳过除RateLimitor和proxy之外的所有路径。使用:except/:only可以像Rails一样设置过滤器吗?

尽管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);
如果您需要比simple
path===req.path
更强大的路由匹配,您可以使用Express内部使用的

更新:-在
express 4.17
req.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);
        }
    };
};

您也可以通过在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"));

无法添加为注释抱歉。

下面是一个使用regexp的
路径的示例,正如@lukaszfiszer的回答所示:

从“express”导入{RequestHandler};
从“path to regexp”导入pathToRegexp;
常数,除非=(
路径:pathToRegexp.Path,
中间件:RequestHandler
):RequestHandler=>{
const regex=pathToRegexp(路径);
返回(请求、恢复、下一步)=>
regex.exec(req.url)?next():中间件(req,res,next);
};
出口违约,除非;

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

app.use("/routeNeedingAllMiddleware", middleware1);
app.use("/routeNeedingAllMiddleware", middleware2);
app.use("/routeNeedingAllMiddleware", middleware3);
app.use("/routeNeedingAllMiddleware", middleware4);
然后像这样设置我的路线

app.post("/routeNeedingAllMiddleware/route1", route1Handler);
app.post("/routeNeedingAllMiddleware/route2", route2Handler);
对于另一个不需要所有中间件的特殊路由,我们设置另一个这样的路由

app.post("/routeNeedingSomeMiddleware/specialRoute", specialRouteHandler);
app.use(“/routenedingsomemiddleware”,middleware2);
应用程序使用(“/routeNeedingSomeMiddleware”,middleware4);
然后像这样设置相应的路由

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

关于这一点的详细文档已提供

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

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

函数(pred、中间件){
返回(请求、恢复、下一步)=>{
if(pred(req)){
next();//跳过此中间件。
}
否则{
中间件(req、res、next);//允许使用此中间件。
}
}
}
用法示例:

app.use(除非(req=>req.method==“PUT”,bodyParser.json());

为此,您可以使用“express除非”npm。您好,请在回答中添加一些说明,并在代码中添加格式。请看更多信息。伟大的答案。应该是解决办法。我同意这值得更多的投票。简单简洁。只需将其全部转换为ES6和一行代码:
const,除非=(中间件,…路径)=>(req,res,next)=>path。一些(path=>path==req.path)?next():中间件(req、res、next)漂亮的解决方案。如果它接受
/users/:id/login
@eric,那就太好了。您可以通过稍微调整路径检查来实现这一点。您可以使用一些逻辑来检查路径的动态部分,并将其剥离或忽略,而不是
path===req.path
。也许一个正则表达式可以做到最好,这里链接的regexp模块的路径不推荐使用。这里是正确的一个:我知道这是旧的,但我想知道为什么有人指出正则表达式是坏的。当路由为
/example\u route
时,您的正则表达式仍然匹配
/
,因此不会跳过路由@纪尧姆在下面给出了正确的答案:
/^\/(?!path1 | pathn)。*$/
我喜欢这个!但我会尽量不使用它的服务器是在重负荷。我会尽量省略路由上的regexp。RegExp匹配确实很快,但字符串比较要快得多。从技术上讲,这并没有错,但实际上并没有涵盖动态路径,例如
/:user/stuff