基于头类型Nodejs返回HTML或JSON

时间:2017-03-29 08:58:52

标签: javascript json node.js express

我的nodeJS Api需要根据标头返回HTML或Json。如果标题是:

Accept = application/json

Api需要返回Json,否则我的Api需要返回一个HTML文件。

这是我在路线上使用的代码:

var app = express();
app.use('/auth', require('./routes/Authenticate'));

在Authenticate文件中我捕获/登录,然后执行登录。如果成功,我重定向到/ users。在/ users中,我使用if语句检查Accept:

router.get('/users', function(req,res){
    if(req.get('Accept') === 'application/json'){
       res.json({ success: true, user: req.user });
    } else {
        res.render("account/profile") //redirect to the file
    }
});

这可行(来自此solution)但有更好的方法吗?因为有20个端点,应用程序正在增长,这对每个端点都是一团糟。

3 个答案:

答案 0 :(得分:0)

您可以将这些操作拆分为2个功能。一个用于验证内容类型,另一个用于执行操作。

router.get('/users', checkIfJson, action);

function checkIfJson(req, res, next) {
    if(!(req.get('Content-Type') === 'application/json')) {
        res.render("account/profile");
        return;
    }
    next();
}

function action(req, res) {
    res.json({ success: true, user: req.user });
    return;
}

如果您编写代码,则可以将checkIfJson重用于其他路径。

答案 1 :(得分:0)

您可以使用自定义函数

包装router.get函数
router.wrappedGet = function (path, callback) {
    router.get(path, function (req, res) {
        if (req.get('Content-Type') === 'application/json') {
            res.render = res.json;
        }
        callback(req, res);
    })
};

答案 2 :(得分:0)

这就是我所做的-似乎非常简单。

router.get("/foo", HTML_ACCEPTED, (req, res) => res.send("<html><h1>baz</h1><p>qux</p></html>"))
router.get("/foo", JSON_ACCEPTED, (req, res) => res.json({foo: "bar"}))

以下是这些中间件的工作方式。

function HTML_ACCEPTED (req, res, next) { return req.accepts("html") ? next() : next("route") }
function JSON_ACCEPTED (req, res, next) { return req.accepts("json") ? next() : next("route") }

我个人认为这是易读的(因此可以维护)。

$ curl localhost:5000/foo --header "Accept: text/html"
<html><h1>baz</h1><p>qux</p></html>

$ curl localhost:5000/foo --header "Accept: application/json"
{"foo":"bar"}

注意:

  • 我建议将HTML路由放在JSON路由之前,因为某些浏览器会接受HTML JSON,因此它们将获得最先列出的路由。我希望API用户能够理解和设置Accept标头,但是我不希望浏览器用户使用,因此浏览器会获得优先选择。
  • ExpressJS Guide中的最后一段讨论了next('route')。简而言之,next()跳到同一路由中的下一个中间件 ,而next('route')退出此路由并尝试下一条。
  • 这里是req.accepts上的参考。