【问题标题】:d3.json, d3.xhr and cross-domain problemsd3.json、d3.xhr 和跨域问题
【发布时间】:2012-05-24 13:21:33
【问题描述】:

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

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);
})

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

    1234563案例(第一个) - 其余案例总是错误?
  1. d3.xhr 方法支持哪些 MIME 类型?

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

    李>

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

【问题讨论】:

  • 我提出这个问题的原因很简单:在接下来的几个月里,我们将大量使用 D3 进行关联数据的可视化

标签: jquery json mime-types d3.js cors


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 对于世界银行,我建议使用d3.jsonp plugin。不过,您需要对其进行修改,以使用WorldBank call structure。调用结构使用 url 查询字符串 &prefix=callbackFunctionName 来指定回调函数,而 d3.jsonp 插件需要 &callback=callbackFunctionName。因此,您可以更改第 10 行和第 24 行,将单词 callback 替换为 prefix(参见 this pastebin)。然后创建一个在响应时执行的回调函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-24
  • 1970-01-01
  • 2019-03-02
相关资源
最近更新 更多