d3.js setrequestheader在ie8中失败

时间:2014-03-14 13:28:51

标签: d3.js

有人可以说如何使用IE8中的d3js xhr接口设置请求标头吗?

代码是这样的:

d3.csv(url).header("accept","text/csv").rows(function(d) {...}).get(function(e,r) {...});

这在IE8中没有预期效果,但在Firefox和Chrome中有效。

我在加载d3之前加载了aight兼容库,之后加载了aight.d3库,但我不认为这些与这个问题有关。

发送请求,但响应类型不正确(它是json而不是csv),因此rows()函数无法获取任何数据。在服务器上,来自IE8的“Accept:”标头值为*/*,但来自其他浏览器的text/csv

当我在裸javascript中编写等效内容时,IE8会正确设置请求标头。

我有d3版本3.4.3。

感谢您的帮助。

此致 --Paul

1 个答案:

答案 0 :(得分:0)

我不是这方面的专家,但通过查看the d3 source code和各种MSDN引用,我认为问题是d3会自动检查您是否使用绝对网址引用,以及如果是这样的话,假设它是一个跨域请求,并为旧的IE切换到IE的XDomainRequest而不是XMLHttpRequest。

相关的d3源代码(line 17-26):

var xhr = {},
      dispatch = d3.dispatch("beforesend", "progress", "load", "error"),
      headers = {},
      request = new XMLHttpRequest,
      responseType = null;

  // If IE does not support CORS, use XDomainRequest.
  if (d3_window.XDomainRequest
      && !("withCredentials" in request)
      && /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest;

第一行测试XDomainRequest对象是否存在(it does for IE8 and up),第二行测试创建的XMLHttpRequest对象是否没有跨域withCredentials属性请求(which only exists in IE10 and up),第三个测试网址是否以" http://"或" https://"。

因此,如果您将绝对URL传递给IE8或IE9浏览器中的任何d3文件抓取功能,它将使用XDomainRequest对象而不是XMLHttpRequest

如果您想实际从跨源服务器获取文件,那么这是好的。如果您的同域服务器期望您指定接受的文件类型,那就不太好了,因为据我所知XDomainRequest doesn't have any way of setting headers,它肯定没有d3的setRequestHeader方法检查(line 96):

  xhr.send = function(method, data, callback) {
    /*...*/
    if (request.setRequestHeader) for (var name in headers) 
           request.setRequestHeader(name, headers[name]);
    /*...*/

那么你如何让它发挥作用?如果您没有执行跨源请求(因此XMLHttpRequest应该正常工作),请尽可能使用相对表示法指定您的URL。否则,您将不得不更改d3源代码或自行创建XMLHttpRequest。