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
Exclude route from express middleware
提问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()));

