【问题标题】:Set up REST routes in Express JS for Ajax only to use with Backbone在 Express JS 中为 Ajax 设置 REST 路由,仅用于 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?

或者有更好的方法吗?请帮忙。

【问题讨论】:

    标签: node.js backbone.js routes express


    【解决方案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 响应。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-23
        • 1970-01-01
        相关资源
        最近更新 更多