将别名查询字符串表示为参数

Express alias query strings as params

本文关键字:参数 表示 字符串 别名 查询      更新时间:2023-09-26

我正在用node, express和jade做一个项目。我想通过以下方式访问内容:

/Page/foo/bar

/Page?Foo=foo&Bar=bar

我希望顶部是底部的别名。

这是我现在的解决方案:

server.js

// some stuff
app.get('/Page/:Foo/:Bar',function(req,res){
    res.render('Page.jade', {Foo: req.params.Foo, Bar: req.params.Bar});
});
app.get('/Page',function(req,res){
    res.render('Page.jade', {Foo: req.query.Foo, Bar: req.query.Bar});
});
// more stuff

Page.jade

doctype html
html
    head
        script var foo = "!{Foo}"; bar = "!{Bar}";
        script(src="/Page.js")
// stuff

Page.js

// stuff with foo and bar, such as:
console.log(foo);
console.log(bar);

我不喜欢这个解决方案的事情是,它迫使我用express单独处理参数和查询(这几乎是重复的代码,但不是很接近以减少它),将它传递给jade,它将其存储在一个变量中,唯一的目的是有一个链接的javascript文件使用这些变量。

通常只是使用查询字符串,我只需要在Page.js中触摸它。是否有一种方法可以设置express来有效地将第一个URL解释为查询字符串,就像第二个URL一样,这样jade文件就不必触及变量了?

  • 选项1:如果你只是想减少代码冗余,也许你可以将你的控制器保存在一个外部文件中,所以你最终会得到这样的东西:

    controllers/fooBarController.js:

    exports.fooBarQueryOrParams = function(req, res) {
        res.render('Page.jade', {
            Foo: req.params.Foo || req.query.Foo,
            Bar: req.params.Bar || req.query.Bar
        });
    }
    

    如果undefined在四年内无效,您也可以使用另一个||操作符添加默认值。

    server.js:

    var fooBarController = require('controllers/fooBarController');
    app.get('/Page/:Foo/:Bar',    fooBarController.fooBarQueryOrParams);
    app.get('/Page',              fooBarController.fooBarQueryOrParams);
    
  • 选项2:同样的事情,但是使用res.locals,所以现在没有必要将任何对象传递给Page.js您的所有视图将通过其名称看到res.locals属性,在这种情况下FooBar(不是res.locals.Foores.locals.Bar)。

    controllers/fooBarController.js:

    exports.fooBarQueryOrParams = function(req, res) {
        res.locals.Foo = req.params.Foo || req.query.Foo;
        res.locals.Bar = req.params.Bar || req.query.Bar;
        res.render('Page.jade');
    }
    

    server.js:

    var fooBarController = require('controllers/fooBarController');
    app.get('/Page/:Foo/:Bar',    fooBarController.fooBarQueryOrParams);
    app.get('/Page',              fooBarController.fooBarQueryOrParams);
    
  • 选项3:总是暴露一切想法res.locals:

    controllers/fooBarController.js:

    exports.fooBarQueryOrParams = function(req, res) {
        res.render('Page.jade');
    }
    

    server.js:

    var fooBarController = require('controllers/fooBarController');
    app.use(function(req, res, next) {
        for (var key in req.params) res.locals[key] = req.params[key];
        for (var key in req.query)  res.locals[key] = req.query[key];
        next();
    });
    app.get('/Page/:Foo/:Bar',    fooBarController.fooBarQueryOrParams);
    app.get('/Page',              fooBarController.fooBarQueryOrParams);
    

我会选择第一个选项,因为我认为你不需要在所有视图中使用FooBar,所以使用res.locals将它们暴露给所有视图而不是只暴露给真正需要它们的视图是没有意义的。

你可以自己设置对象属性,然后继续下一个路由等等

app.use('/Page/:Foo/:Bar',function(req, res, next){
    for (var key in req.params) {
        req.query[key] = req.params[key];
    }
    next();
});