Backbone POST JSON

时间:2014-02-01 00:42:07

标签: javascript backbone.js

我是Backbone的新手,并让GET与测试端点合作,例如,

var Attributes = Backbone.Collection.extend({
  url: '//127.0.0.1:8080/blah'
});

var AttributeListView = Backbone.View.extend({
  el: '.page',
  render: function () {
    var that = this;
    var attributes = new Attributes();
    attributes.fetch({
      success: function (attributes) {
        var template = _.template($('#attribute-list-template').html(), {attributes: attributes.models});
        that.$el.html(template);
      }
    })
  }
})

但是,真正的端点需要一个带有JSON有效负载的POST,我无法使语法工作。我试过这样的事情

var AttributeListView = Backbone.View.extend({
  el: '.page',
  render: function () {
    var that = this;
    var attributes = new Attributes();
    attributes.fetch({
      type: "POST",
      contentType: "application/json; charset=utf-8",
      dataType: "json",
      data: '{ "searchtext": "abc" }',
      success: function (attributes) {
        var template = _.template($('#attribute-list-template').html(), {attributes: attributes.models});
        that.$el.html(template);
      }
    })
  }
})

@Rusty,无论有没有http,网址都能正常运行,浏览器现在可以正常处理。在进一步挖掘之后,似乎这是一个CORS问题。我知道端点设置了Access-Control-Allow-Origin:*但仅用于POST请求,我认为请求设置不正确,这是我从Chrome调试中获得的内容

Request URL:http://127.0.0.1:8080/blah
Request Headers CAUTION: Provisional headers are shown.
Accept:application/json, text/javascript, */*; q=0.01
Cache-Control:max-age=0
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Origin:http://localhost:8000
Referer:http://localhost:8000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.102 Safari/537.36
Form Dataview sourceview URL encoded
{ "searchtext": "abc" }:

从控制台日志

XMLHttpRequest cannot load http://127.0.0.1:8080/blah. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. 

2 个答案:

答案 0 :(得分:2)

正如您所说,这是 CORS 问题。

特别是在POST PUTDELETE请求中,浏览器实际执行了2个请求。

在幕后发生的事情是,在真实请求之前,浏览器发送预检OPTION请求,这就像要求服务器获得实际请求的许可一样。 (请在服务器日志中检查哪种类型的请求来自浏览器)

要允许CORS请求,服务器必须正确处理此方案,并使用一组OPTION响应CORS Headers请求,如下所示:

Access-Control-Allow-Origin: http://some.another.domain
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type
Content-Type: text/html; charset=utf-8 

在CORS标头中(均以Access-Control-Allow- *开头),服务器指定以下权限:

  • 允许哪个域执行请求,允许任何外部域*
  • 从这些域接受哪些HTTP方法。
  • 接受哪个请求标头,您可以添加所需的所有标头。 例如,要处理不同域之间的HTTP身份验证,这是使用外部API的常见方案,您需要添加授权标头。

如果服务器正确响应OPTION请求,浏览器将执行实际请求。

这是正确处理Rails的CORS请求的指南,但它很容易适用于所有服务器端语言/框架:http://leopard.in.ua/2012/07/08/using-cors-with-rails/

答案 1 :(得分:0)

他的评论中的Rustytoms是正确的。你不必设置整个网址,你可以写/blah,但我认为你遇到的问题是不同的。

默认情况下,当您在新模型上调用fetch时,Backbone将生成GET请求以获取遵循REST原则的信息。要检查模型是否是新的,Backbone使用model.isNew()方法,它基本上只检查模型是否具有id。如果你在模型上调用save()方法,那么Backbone将为'/ users'生成一个POST请求,如果模型不是新的,它将生成一个SYNC请求'/users/:id'。 p>

此方法将所有功能委托给Backbone.sync()方法。因此,如果您的后端API不遵循REST原则,您可以执行的操作是使用AJAX调用替换模型中的fetch()方法,或者创建一个新方法。关于AJAX请求的“成功”,您可以使用model.set()将属性保存到模型中。

我建议您阅读Backbone documentation以了解这些方法,因为一切都很清楚。