11

我今天做了几个与我们可以使用 d3 加载 json 文件的方式有关的测试,因为我对这个问题很感兴趣:d3.json works but $.getJson failed。然而,我做的一些测试有点棘手。

d3.xhr("http://dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fdbpedia.org&query=select+*+where+%7B%3Chttp%3A%2F%2Fdbpedia.org%2Fresource%2FRoger_Federer%3E+%3Fp+%3Fo+filter%28lang%28%3Fo%29+%3D+%27en%27%29%7D%0D%0A&debug=on&timeout=&format=application%2Fsparql-results%2Bjson&save=display&fname=", function(data)
console.log("success1"); 
alert(data);
});

d3.json("http://dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fdbpedia.org&query=select+*+where+%7B%3Chttp%3A%2F%2Fdbpedia.org%2Fresource%2FRoger_Federer%3E+%3Fp+%3Fo+filter%28lang%28%3Fo%29+%3D+%27en%27%29%7D%0D%0A&debug=on&timeout=&format=application%2Fsparql-results%2Bjson&save=display&fname=", function(data){              console.log("success2");
alert(data);
});


d3.xhr("http://api.worldbank.org/countries/BRA/indicators/BX.KLT.DINV.CD.WD?per_page=10&date=2007:2012&format=json", function(data){
console.log("success3");
alert(data);
})

d3.json("http://api.worldbank.org/countries/BRA/indicators/BX.KLT.DINV.CD.WD?per_page=10&date=2007:2012&format=json", function(data){
console.log("success4");
alert(data);
})

我知道问题可能与至少 2 个原因有关:MIME 类型和 CORS,但我无法理解其他几件事:

  1. 如果始终执行回调(有时甚至很难使用 OK 200,这也可能是从 jQuery 的 .ajax() 和 .getJSON() 方法看到的错误)为什么我只能在一种情况下看到数据(第一种情况) - 其余的情况总是错误?

  2. d3.xhr 方法支持哪些 MIME 类型?

  3. 如果 d3.json 只是 d3.xhr 的一个很好的包装器,为什么示例 1 有效而示例 2 无效......?我想澄清一下。我主要将 d3 与来自我的服务器的文件一起使用,但在某些情况下,我还必须使用一些外部数据,而且使用 D3 也能很好地做到这一点,而不仅仅是使用 jQuery。

我认为应该有一个列表,其中包含这些方法接受的所有 MIME 类型。

4

1 回答 1

14

第一个请求成功而第二个请求失败的原因与 dbpedia.org 服务器的配置有关。该d3.json()函数做了两件事:

  1. 它将Accept标头设置为 mimetypeapplication/json

  2. 它使用解析响应JSON.parse()

数字 1 是问题 - dbpedia.org 服务器正在返回对标头的406 (Unacceptable)响应Accept: application/json。我不确定为什么这是真的,但是鉴于您发送的 URL 参数,它看起来像服务器期望的application/sparql-results+json那样 - 实际上,指定这个 mime 类型d3.xhr()成功,而使用application/json失败。

使用世界银行数据,请求失败,因为服务器未启用 CORS。在不启用 CORS 的情况下调用远程 API 的唯一浏览器内方法是使用 JSONP(假设 API 支持它)。碰巧, data.worldbank.com确实支持 JSONP,但 D3 不支持 - 您需要自己处理它或使用像 jQuery 这样的第三方库来发出请求。

一般来说,D3 并没有像 jQuery 和其他库那样优先考虑真正强大的 AJAX 支持,因为这不是它的重点——所以如果你想加载各种各样的外部资源,你可能应该使用 3rd-party 库对经过仔细调整的 AJAX 调用有更多支持。根据您要加载的内容,另一种选择是在您自己的服务器上设置一个代理,该代理可以调用​​远程 API,然后通过本地 HTTP 调用将数据返回给您的可视化 - 在这种情况下,所有 D3 的加载器都应该工作正常。

于 2012-05-17T22:30:42.587 回答