0

我正在尝试编写一个简单的函数来从 javascript 中的 XML 加载数组。我已经成功地将 AJAX 结果发送到success:调用时使用该字段的函数$.ajax(...)

另外,我注意到函数的返回值$.ajax(...)是 an Object,它有字段responseTextand responseXML(我很乐意使用)。但是,即使我可以在控制台的树中看到它们,尝试通过它们访问它们.responseText也不起作用(因此打印undefined,如果我要尝试查找一些垃圾字符串,则相同.this_does_not_exist)。

我将使用几个不同的 XML 文件几乎完全相同地执行此操作,我想使用代码来执行此操作。我不满足于简单地让success:参数将结果踢到单独的函数的原因是因为我可能会多次使用数据,但只想加载一次。我正在尝试将加载和使用 XML 分开,这样它就不会被加载多次。

你能告诉我为什么responseText在我输出时出现xml_ret,但无法访问xml_ret.responseText吗?

非常感谢您的帮助和耐心。


注意:test.xml要从同一目录加载,您需要以这种方式启动 Chrome 或 Chromium:

chromium-browser --allow-file-access-from-files 

测试.html:

<html>
<head>
<script type="text/javascript" 
        src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

    <script type="text/javascript">
      function print_XML(xml)
      {
      console.log( "in printXML" );
      console.log(xml);

      $(xml).find("point").each(function()
      {
      var loaded_row = [ parseInt($(this).attr("number_protein_groups")), parseInt( $(this).attr("log_likelihood") ) ];
      console.log( loaded_row );
      });
      }

      function load_and_print_XML(fname)
      {
    console.log( "in load_and_print_XML" );

      xml_ret = $.ajax({
      type: "GET",
      url: fname,
      dataType: "xml",
      success: print_XML
       });

    console.log( "xml_ret" );
    console.log( xml_ret );
    console.log( xml_ret.responseText );
      }

    </script>

</head>
  <body>
    <script type="text/javascript">
      xml_data = load_and_print_XML("test.xml");
      /* do something with xml_data here */
    </script>
  </body>
</html>

测试.xml

<?xml version="1.0" encoding="utf-8" ?>
<results>
  <replicate_result graph_filename="yeast_1.pivdo">
    <point number_protein_groups="10" log_likelihood="20"/>
    <point number_protein_groups="20" log_likelihood="40"/>
    <point number_protein_groups="40" log_likelihood="60"/>
    <point number_protein_groups="50" log_likelihood="50"/>
    <point number_protein_groups="60" log_likelihood="55"/>
  </replicate_result>
</results>

我的控制台:

in load_and_print_XML
test.html:30xml_ret
test.html:31
Object
abort: function (a){a=a||"abort",p&&p.abort(a),w(0,a);return this}
always: function (){i.done.apply(i,arguments).fail.apply(i,arguments);return this}
complete: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
done: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
error: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
fail: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
getAllResponseHeaders: function (){return s===2?n:null}
getResponseHeader: function (a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c}
isRejected: function (){return!!i}
isResolved: function (){return!!i}
overrideMimeType: function (a){s||(d.mimeType=a);return this}
pipe: function (a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()}
progress: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
promise: function (a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}
readyState: 4
responseText: "<?xml version="1.0" encoding="utf-8" ?>↵&lt;results>↵  <replicate_result graph_filename="yeast_1.pivdo">↵    <point number_protein_groups="10" log_likelihood="20"/>↵    <point number_protein_groups="20" log_likelihood="40"/>↵    <point number_protein_groups="40" log_likelihood="60"/>↵    <point number_protein_groups="50" log_likelihood="50"/>↵    <point number_protein_groups="60" log_likelihood="55"/>↵  </replicate_result>↵&lt;/results>"
responseXML: Document
setRequestHeader: function (a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this}
state: function (){return e}
status: 200
statusCode: function (a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this}
statusText: "success"
success: function (){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this}
then: function (a,b,c){i.done(a).fail(b).progress(c);return this}
__proto__: Object
test.html:32undefined
test.html:9in printXML
test.html:10
Document
<results>​
<replicate_result graph_filename=​"yeast_1.pivdo">​…​&lt;/replicate_result>​
</results>​
test.html:15[10, 20]
test.html:15[20, 40]
test.html:15[40, 60]
test.html:15[50, 50]
test.html:15[60, 55]
4

3 回答 3

2

对于这个问题:

你能告诉我为什么在我输出 xml_ret 时出现 responseText,但 xml_ret.responseText 无法访问吗?

发生这种情况是因为当您对一个对象(例如在 chrome 中)执行 console.log 时,会在控制台中保留对该对象的引用。如果对象发生更改,这些更改将由 chrome 的控制台反映。

所以发生的事情是当你这样做时:

console.log( "xml_ret" );
console.log( xml_ret );
console.log( xml_ret.responseText );

ajax 请求尚未完成,responseText 仍未分配,这就是它显示为未定义的原因。但是,打印的 xml_ret 对象是对对象的引用,因此当 ajax 请求完成时,如果您检查控制台上的值,它具有“responseText”属性,因为它已经设置。

你可以看到,如果你调试代码并在这一行添加一个断点:

console.log( xml_ret.responseText );

查看文件 xml_ret 时,它没有“responseText”属性。

PS:我肯定需要查看此评论。想得太晚了:P

于 2012-04-13T23:10:50.600 回答
1

问题是控制台将更新对象,如果它们得到更新而不是字符串。

因此,如果您调用 ajax 调用,该函数将直接返回一个对象,但responseText由于调用尚未完成,所以该对象将是未定义的。

因此,如果您想使用,responseText您应该在成功时使用:

function print_XML(xml, s, jqXHR) { // there are 3 arguments past the third one is the same as the return of $.ajax
    console.log( "in printXML" );
    console.log(xml);

    $(xml).find("point").each(function()
    {
    var loaded_row = [ parseInt($(this).attr("number_protein_groups")), parseInt( $(this).attr("log_likelihood") ) ];
    console.log( loaded_row );
    });

    console.log(jqXHR);
    console.log(jqXHR.responseText); // now it works!
}​
于 2012-04-13T22:53:44.390 回答
0

responseText 在您输出 xml_ret 时显示,因为这就是 ajax 函数在 jQuery 中的工作方式。这是回调中返回的内容

成功(数据,文本状态,jqXHR)

因此,当您尝试获取 xml_ret 的属性时,它会失败,因为它只是 XML 数据而不是对象。第三个参数是你所期望的,因为它是一个 jquery ,所以它也略有修改。

于 2012-04-13T23:04:52.633 回答