2012-05-16 66 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. (甚至有時使用OK 200也是一個難題,從jQuery的.ajax()和.getJSON()方法中可以看出這也是一個錯誤)爲什麼我只能看到一個案例中的數據(第一個案例) - 其餘案例都是總是錯誤?

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

  3. 如果d3.json只是d3.xhr的一個很好的包裝爲什麼示例1有效並且示例2不起作用...?我想澄清一下。我主要是使用d3與我的服務器上的文件,但也有這樣的情況,當我也必須使用一些外部數據,並且這對D3也是很好的,不僅僅是使用jQuery。

我認爲應該有一個列表,所有這些方法接受的MIME類型。

+0

我之所以問這個很簡單:我們將大量使用D3爲鏈接的數據可視化,在未來幾個月 – paxRoman

回答

12

第一次請求成功而第二次失敗的原因與dbpedia.org服務器的配置有關。該d3.json()功能做了兩兩件事:

  1. 它的Accept頭設置爲MIME類型application/json

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

1號的響應是問題 - DBpedia中。 org服務器正在爲Accept: application/json標題返回406 (Unacceptable)的響應。我不確定爲什麼這是真的,但鑑於你發送的URL參數,它看起來像服務器預期application/sparql-results+json - 實際上,指定此MIME類型與d3.xhr()成功,而使用application/json失敗。

由於世界銀行的數據,請求失敗,因爲服務器不是CORS-enabled。在沒有啓用CORS的情況下調用遠程API的唯一瀏覽器內部方式是使用JSONP(假設API支持它)。碰巧,data.worldbank.com does support JSONP,但D3不 - 你需要自己處理它,或者使用像jQuery這樣的第三方庫來提出請求。

一般來說,D3沒有優先考慮真正健壯的AJAX支持jQuery和其他庫的方式,因爲這不是它的焦點 - 所以如果你想加載各種各樣的外部資源,你應該這樣做第三方庫更加支持仔細調整的AJAX調用。根據您想要加載的內容,另一種選擇是在您自己的服務器上設置一個代理,該代理可以調用​​遠程API,然後通過本地HTTP調用將數據返回給您的可視化對象 - 在這種情況下,D3的所有加載器應該工作正常。

+1

對於依世界銀行,我使用會建議[d3.jsonp插件](https://github.com/d3/d3-plugins/tree/master/jsonp)。儘管如此,您仍然需要修改它,以便與[WorldBank調用結構](http://data.worldbank.org/node/11)一起使用。調用結構使用url查詢字符串'&prefix = callbackFunctionName'來指定回調函數,而d3.jsonp插件需要'&callback = callbackFunctionName'。 所以你可以改變第10和第24行,用'前綴'代替'callback'這個詞(參見[this pastebin](http://pastebin.com/MLs0LaKW))。 然後創建一個回調函數來執行響應。 – wgardiner

0

有問題的實施例1缺失之間

「的功能(數據)」 和 「控制檯」 的大括號。

它爲我曾經改寫爲function(data) { console