我想隔离一段代码,该代码会检查req.params
或req.body
以查找每个请求所需的值。我发现的是,如果我尝试在app.use(app.router)
之前访问这些值,那么请求尚未被解析为包含这些对象。如果我尝试在 app.use(app.router)
之后插入中间件,那么它将一起跳过。
我可以在一个地方处理这些值,以便下游路径和模型可以使用这些工作吗?
答案 0 :(得分:12)
只需使用每条路线内联中间件,
const middleware = (req, res, next) => {
console.log(req.params.id);
next();
};
app.get('/test/:id', middleware, (req, res) => {
res.send('hi');
});
答案 1 :(得分:10)
你无法做你想做的事。 https://github.com/strongloop/express/issues/2088非常清楚地解释了这一点。
我一直试图做你想做的事情一段时间,没有成功。我终于在github中找到了这个问题。
答案 2 :(得分:2)
由于我的原始答案无法从网址获取路线参数,例如/things/:foo
(虽然它会得到querystring和req.body params),它不会按照我们想要的方式工作。但另一种选择是编写一个包装函数,它可以满足你的需要,并将它应用到你的路由中间件:
function checkForParam (fn) {
return function(req, res, next) {
if (req.param('foo') != 'bar') {
return res.send(403, 'No way Jose!');
}
fn (req, res, next);
};
}
然后添加路线:
app.get('/things/:foo', checkForParam(function(req, res, next) {
// your middleware code here
});
这将运行检查,并且只有在通过集合时才会继续运行到自定义路由中间件。
答案 3 :(得分:1)
我喜欢这样:
const controller = function (name, method) {
return function (req, res) {
// COERCE ID
if (req.method === 'GET' || req.method === 'DELETE') {
var _id = req.params && req.params._id || false
if (/^[0-9a-f]{24}$/.test(_id)) {
req.params._id = new ObjectID(_id)
}
else if (_id) {
return res.status(404).send('Page not found.')
}
}
require('./api/' + name + '.js')[method](req, res)
}
}
然后:
app.get('/api/post/:_id', controller('posts', 'get'))
答案 4 :(得分:0)
还有一个问题:您使用的是Express v。 3或4 ???
这在这里非常重要,因为第4节中的概念不同(又名更好)。
e.g。 https://github.com/visionmedia/express/wiki/Migrating-from-3.x-to-4.x
app.use(app.router); //< ---此行将被删除
答案 5 :(得分:0)
尝试了一种简单的核心层解决方法,以便在进入路由器之前先在路由器中获取URL参数
我需要验证URL param id(它是项目ID),并检查各个用户是否可以访问它
我不想在所有路由中将其用作中间件,因此使用了split
函数来提取URL参数中的项目ID
router.use(apiauthenticated,(req,res,next)=>{
try {
//req.params.projectid
let temp_projectid=req.originalUrl.split("/") //Getting all endpoints and params
let last_element=temp_envid[temp_envid.length-1] //Get last element from array for URL params
let projectid =last_element.includes("?") ? last_element.split("?")[0] : last_element //Returning URL params with or without query params
if(projectid === "" ){
//if it is null throwing error
throw "Please provide required projectid";
}
//Db validation here with projectid
next();
} catch (error) {
res.status(400).send(error);
return null;
}
})
apiauthenticated
是用于验证API密钥的中间件
使用last_element.includes("?") ? last_element.split("?")[0] : last_element
处理查询参数
答案 6 :(得分:-1)
您可以简单地添加一个始终在其他路由之前运行的通配符路由,而不是尝试通过自定义中间件执行此操作,并检查其中的参数:
app.get('/*', function(req, res, next) {
if (req.param('foo')) {
// Do something
return next(); // or return res.send(403, 'no way!'), or whatever.
}
return next();
});