7

我正在使用带有 Express 的 Node.js 重写现有网站。

该站点的前端将使用 Backbone JS,因此我需要使所有必要的路由符合本机 Backbone 同步。现在大多数 URL 的客户端和 Backbone 同步将是相同的。但它们不适用于常规 GET,因为它们需要返回 JSON。

所以我在想,将扩展添加到 Backbone 中的模型/集合 URL 是否是一个好主意,例如.json, 和 Express 中的每个路由都有这个:

app.get('/p/:topCategory/:category/:product.:format', function(req, res) { ... });

我们在哪里if (req.params.id == 'json')发送 JSON,否则我们渲染 HTML?

还是有更好的方法?请帮忙。

4

4 回答 4

12

更好的方法是使用 Express 3.x 中的内容协商功能,即res.format

https://github.com/visionmedia/express/blob/master/lib/response.js#L299-378

res.format({
  text: function(){
    res.send('hey');
  },

  html: function(){
    res.send('<p>hey</p>');
  },

  json: function(){
    res.send({ message: 'hey' });
  }
});

你的方法也可以,Yammer for ex。正在使用相同的方法:http: //developer.yammer.com/api/#message-viewing

于 2012-06-09T09:42:22.667 回答
6

Accept在您的请求中使用标头:Accept: application/json如果您想要接收 JSON,Accept: text/HTML如果您想要 HTML。

于 2012-06-09T03:18:43.907 回答
2

另一种方法还检查是否为 jQuery 等设置了“X-Requested-With”标头。

var onlyAllowJsonRequests = function (req, res, next) {

    var acceptJson = (req.accepted.length && _.any(req.accepted, function (acc) { return acc.value.indexOf("json") !== -1 }));

    // also check that "X-Requested-With": "XMLHttpRequest" header is set
    if (acceptJson && (req.xhr === true)) {
        next();
    } else {
        res.send(406, "Not Acceptable");
    }
};

app.use(onlyAllowJsonRequests);

NB 下划线是一种依赖。

于 2012-12-07T12:11:37.910 回答
2

我认为正确的方法是在您的应用程序中实现内容协商。是的,Express 3.x 工具是一种实现方式,并且可以直接回答您的问题,但我认为这不是最好的方式,因为它将内容协商责任置于路由逻辑中。我认为这不是一个好地方,因为它不遵循单一责任原则,将内容协商放在路由逻辑中。

我尝试在我的博客引擎中实现内容协商;回顾这可能有助于指导您朝着一个好的方向前进。要点是代码通过内容协商逻辑确定文件扩展名。然后,使用文件扩展名,它想找到相应的视图文件,将其呈现为响应并将其发送回客户端。这个想法是它根据内容协商以请求的表示形式响应请求的资源。路由逻辑只指定一个视图,但不知道内容协商。这发生在路由逻辑之外,这使得设计更加灵活。

这种设计的结果是能够请求资源的特定表示,例如:

http://blog.joeyguerra.com/index.json并获得 JSON 表示 http://blog.joeyguerra.com/index.phtml并获得部分(或 HTML 片段)HTML 表示 http://blog.joeyguerra。 com/index.xml并获取 XML 表示。

于 2013-11-16T16:53:40.870 回答