2012-05-16 29 views
9

私はd3でjsonファイルをロードする方法に関するいくつかのテストを今日行いました。なぜなら、私はこの質問に興味があったからです:d3.json works but $.getJson fails。しかし、私が作ったテストのいくつかはややこしいものです。d3.json、d3.xhr、およびクロスドメインの問題

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. コールバックが常に実行された場合( jQueryの.ajax()メソッドと.getJSON()メソッドから見られるようにエラーでもあるOK 200の場合もあります)なぜ、私は1つのケース(最初のケース)でデータを見ることができますか?残りのケースは常にエラー?

  2. d3.xhrメソッドでサポートされているMIMEタイプは何ですか?

  3. d3.jsonがd3.xhrの素晴らしいラッパーだったとしたら、例1はうまくいっていて、例2は機能しません... ...?私はいくつかの説明をしたいと思います。私は主にサーバーからのファイルでd3を使用しますが、いくつかの外部データを使用する必要がある場合もあります.jQueryだけでなく、D3でもこれを行うのは本当にうれしいでしょう。

これらの方法で受け入れられるすべてのMIMEタイプのリストがあるはずです。

+0

これを尋ねるための私の理由は単純です:私たちはWorldBankのために、私が使用してお勧めしたい – paxRoman

答えて

12

第1の要求が失敗したときに最初の要求が成功する理由は、dbpedia.orgサーバーの構成と関係しています。 DBpediaの -

  1. それはMIMEタイプapplication/json

  2. それはJSON.parse()

ナンバー1を使用して応答を解析する問題であるにAcceptヘッダーを設定します。d3.json()関数は2つのことを行います。 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サポートに優先順位を付けませんでした。なぜなら、それは焦点ではないからです。多種多様な外部リソースをロードする場合は、慎重に調整されたAJAX呼び出しのサポートが強化されたサードパーティのライブラリです。ロードする内容に応じて、リモートAPIを呼び出すことができる独自のサーバーにプロキシを設定し、ローカルHTTP呼び出しを介してビジュアライゼーションにデータを戻すこともできます。その場合、D3のローダはすべてうまく動作します。

+1

次のヶ月の間にリンクされたデータの視覚化のために多額のD3を使用します。 [d3.jsonp plugin](https://github.com/d3/d3-plugins/tree/master/jsonp)。あなたは[WorldBankの呼び出し構造](http://data.worldbank.org/node/11)で作業するには、それを変更する必要があります。 call構造体はurlクエリ文字列 '&prefix = callbackFunctionName'を使用してコールバック関数を指定し、d3.jsonpプラグインは'&callback = callbackFunctionName'を要求します。 したがって、 'callback'という単語を' prefix'( "this pastebin"(http://pastebin.com/MLs0LaKW)を参照)に置き換えて、10行目と24行目を変更することができます。 次に、応答時に実行されるコールバック関数を作成します。 – wgardiner

0

問題の例1は、

"機能(データ)" と "コンソール" との間の開口中括弧が欠落しています。

それはかつてなどfunction(data) { consoleのように書き換える私の作品