在 Express JS 中为 Ajax 设置 REST 路由,仅用于 Backbone
Posted
技术标签:
【中文标题】在 Express JS 中为 Ajax 设置 REST 路由,仅用于 Backbone【英文标题】:Set up REST routes in Express JS for Ajax only to use with Backbone 【发布时间】:2012-06-13 01:22:09 【问题描述】:我正在使用带有 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?
或者有更好的方法吗?请帮忙。
【问题讨论】:
【参考方案1】:我认为正确的做法是在您的应用程序中实施内容协商。是的,Express 3.x 工具是一种实现方式,并为您的问题提供了直接答案,但我认为这不是最好的方式,因为它将内容协商责任置于路由逻辑中。我认为这不是一个好地方,因为它不遵循single responsibility 原则,将内容协商放在路由逻辑中。
我在blog engine 中尝试实施内容协商;回顾这可能有助于指导您朝着一个好的方向前进。要点是代码通过内容协商逻辑确定文件扩展名。然后,使用文件扩展名,它想找到相应的视图文件,将其呈现为响应并将其发送回客户端。这个想法是,它根据内容协商以请求的表示形式响应请求的资源。 routing logic 只指定一个视图,但不知道内容协商。这发生在路由逻辑之外,这使得设计更加灵活。
这种设计的结果是能够请求资源的特定表示,例如:
http://blog.joeyguerra.com/index.json 并获取 JSON 表示 http://blog.joeyguerra.com/index.phtml 并获取部分(或 HTML 片段)HTML 表示 http://blog.joeyguerra.com/index.xml 并获取 XML 表示。
【讨论】:
【参考方案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 下划线是一种依赖。
【讨论】:
【参考方案3】:更好的方法是使用 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。正在使用相同的方法:http://developer.yammer.com/api/#message-viewing
【讨论】:
感谢您的回复。我没有在 Express 文档中找到 res.format() 。但我找到了 req.is('html') 或 req.is('json')。我想任何一个都应该工作,但 res.format() 看起来更好,因为它的功能,我不需要为 res.is() 使用 if/else if。 它还没有在文档中,因为 Express 3.x 是新的,并且需要更新站点(据我所知,这将很快发生)。【参考方案4】:在您的请求中使用 Accept
标头:Accept: application/json
如果您想要接收 JSON,Accept: text/HTML
如果您想要 HTML。
【讨论】:
如何在 Node 端进行设置? 您使用标准的 javascript 文本解析技术(正则表达式等)在req.headers
中查找以 Accept:
开头的任何内容。我这样做的方式是,如果其中任何一个请求 JSON,则发送一个 JSON 响应,如果没有一个请求,则发送一个 HTML 响应。以上是关于在 Express JS 中为 Ajax 设置 REST 路由,仅用于 Backbone的主要内容,如果未能解决你的问题,请参考以下文章
在我的 express 中为 node.js 设置了 cors 但仍然给出关于 cors 的相同错误
使用 ASP.NET MVC 在 JS 文件中为 jQuery 设置 ajax url
在 express.js 中为 node.js 使用 jsonp
如何使用 express.js 在 Ajax 调用中实现 CSRF 保护(寻找完整示例)?