【问题标题】:Backbone.js with XML response - parse function not called before parse error带有 XML 响应的 Backbone.js - 在解析错误之前未调用解析函数
【发布时间】:2012-05-24 19:55:12
【问题描述】:

我正在使用 Backbone.js 构建一个通常通过 JSON 与 Web 服务通信的应用程序。

一个 Web 服务将在成功时返回 JSON 或在错误时返回 XML(聪明,是吗?)。我需要解析这个 XML 响应来确定错误,但是 Backbone 以 JSON 为中心的思维给我带来了问题。

我有一个包含解析函数的集合。解析函数总是在服务返回 JSON 时被调用,在这种情况下我只是返回响应对象。但是,当服务返回 XML 时,我的 fetch 调用的错误回调函数被调用,并传递了一个带有 arguments[1]parseerror 的错误对象。进一步挖掘显示有一个意想不到的< 字符。

为什么在抛出 parseerror 之前没有调用我的 parse 函数来解析 XML?此外 - 为什么在成功的 JSON 调用中,它传递了一个 JavaScript 对象(表明 JSON 字符串已经被解析)?解析函数不应该做解析吗?

下面的相关代码,任何建议都非常感谢。

var myCollection = Backbone.Collection.extend({

initialize : function() {
    ...
},

fetch: function(options) {

    var options = {data: {...}, error: this.onFetchError};

    Backbone.Collection.prototype.fetch.call(this, options);
},

onFetchError: function(arg1, arg2, arg3) {

    debugger
},

parse: function(response) {

    debugger
    if(typeof response === 'object') {
        return response;
    }
}
});

return myCollection;

【问题讨论】:

  • 解析错误可能来自 jQuery 或 XMLHttpRequest,而不是来自主干。返回的响应是否带有适当的 Content-Type,例如 application/xml?返回的 XML 格式是否正确?
  • @breischl 感谢您的输入,这方面的一切看起来都不错 - Content-Type 是 application/xmlw3schools.com/xml/xml_validator.asp 告诉我 XML 格式正确
  • 是否有人在某个地方在请求中设置了 jQuery dataType 选项?可能是在$.ajaxSetup()$.ajaxStart() 通话中完成的?如果不是这样,我想尝试在 Backbone successerror 函数中设置断点,看看是否会产生更多信息。

标签: xml ajax parsing backbone.js


【解决方案1】:

文档对此含糊不清。 Model.fetch([options]) 使用 Backbone.syncdocs for sync 表示您可以使用“所有其他 jQuery 请求选项”,这意味着 jQuery.ajax 支持的任何内容。

因此,要将响应作为原始文本获取,您可以这样做:

this.fetch({ dataType: 'text' });

然后在您的parse 函数中,您可以随心所欲地处理响应。

旁注:我在尝试获取模型以获取 XML 并使用该数据类型进行测试时发现了这一点。

【讨论】:

    【解决方案2】:

    如果您查看默认提取:

    fetch: function(options) {
      options = options ? _.clone(options) : {};
      var model = this;
      var success = options.success;
      options.success = function(resp, status, xhr) {
    
        //-->parse only invoked on success     
        if (!model.set(model.parse(resp, xhr), options)) return false;
        if (success) success(model, resp);
      };
    
      //-->parse not invoked on error
      options.error = Backbone.wrapError(options.error, model, options);
      return (this.sync || Backbone.sync).call(this, 'read', this, options);
    }
    

    您会看到 parse 永远不会在错误条件下被调用。但是,wrapError(如下所示)将为您提供原始响应:

    Backbone.wrapError = function(onError, originalModel, options) {
      return function(model, resp) {
        resp = model === originalModel ? resp : model;
        if (onError) {
          onError(originalModel, resp, options);
        } else {
          originalModel.trigger('error', originalModel, resp, options);
        }
      };
    }; 
    

    所以你的 arg2 会有响应,并且可以想象,你可以将它传递给你的 parse 函数。

    【讨论】:

      猜你喜欢
      • 2012-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-23
      相关资源
      最近更新 更多