快速访问req.params的中间件

时间:2014-03-17 19:12:40

标签: node.js express

我想隔离一段代码,该代码会检查req.paramsreq.body以查找每个请求所需的值。我发现的是,如果我尝试在app.use(app.router)之前访问这些值,那么请求尚未被解析为包含这些对象。如果我尝试在 app.use(app.router)之后插入中间件,那么它将一起跳过。

我可以在一个地方处理这些值,以便下游路径和模型可以使用这些工作吗?

7 个答案:

答案 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();

});