2012-05-16 1 views
9

Сегодня я провел несколько тестов, связанных с тем, как мы можем загружать json-файлы с d3, потому что меня заинтриговал этот вопрос: 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, который также может быть ошибкой, как видно из методов .ajax() и .getJSON() jQuery), почему я могу видеть данные только в одном случае (первый) - остальные случаи всегда ошибки?

  2. Какие типы MIME поддерживаются методом d3.xhr?

  3. если d3.json был просто приятной упаковкой для d3.xhr, почему пример 1 работает, а пример 2 не работает ...? Я хотел бы получить некоторые разъяснения. В основном я использую d3 с файлами с моего сервера, но есть случаи, подобные этому, когда мне также приходится использовать некоторые внешние данные, и было бы очень полезно сделать это также с D3, а не только с jQuery.

Я думаю, что должен быть список со всеми типами MIME, принятыми этими методами.

+0

моя причина для спрашивать это просто: мы будем использовать D3 в значительной степени для связанных визуализации данных в последующие месяцы – paxRoman

ответ

12

Причина, по которой первый запрос завершается успешно, а второй не соответствует конфигурации сервера dbpedia.org. d3.json() функция делает две вещи:

  1. Он устанавливает заголовок Accept к MimeType application/json

  2. Он анализирует ответ, используя JSON.parse()

номер 1 является вопрос - DBpedia. сервер org возвращает ответ 406 (Unacceptable) для заголовка Accept: application/json. Я не уверен, почему это правда, но с учетом параметров URL, которые вы отправляете, похоже, что сервер ожидает application/sparql-results+json вместо этого - действительно, этот тип mime с d3.xhr() преуспевает, а сбой application/json.

С данными Всемирного банка запрос терпит неудачу, так как сервер не является CORS-enabled. Единственный в браузере способ сделать вызов удаленного API без включенного CORS - использовать JSONP (если API поддерживает его). Как это бывает, data.worldbank.com does support JSONP, но D3 - нет - вам придется либо заниматься этим самостоятельно, либо использовать стороннюю библиотеку, такую ​​как jQuery, чтобы сделать запрос.

В целом, D3 не имеет приоритетов в отношении действительно надежного AJAX, поддерживающего способ использования jQuery и других библиотек, поскольку это не является его фокусом - поэтому, если вы хотите загрузить большое количество внешних ресурсов, вероятно, вы должны сделать это с помощью Сторонняя библиотека, которая имеет большую поддержку тщательно измененных вызовов AJAX. В зависимости от того, что вы хотите загрузить, другой вариант заключается в настройке прокси-сервера на вашем собственном сервере, который может вызывать удаленные API-интерфейсы, а затем вернуть данные к вашим визуализации через локальный HTTP-вызов - в этом случае все загрузчики D3 должны работа хорошо.

+1

Для Worldbank, я хотел бы предложить, используя [d3.jsonp plugin] (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'' префиксом' (см. [Этот pastebin] (http://pastebin.com/MLs0LaKW)). Затем создайте функцию обратного вызова, которая будет выполнена при ответе. – wgardiner

0

Проблематичный пример 1 отсутствует открывающей фигурной скобки между

"функции (данные)"

и "консоли".

Это работает для меня один раз переписать в виде function(data) { console и т.д.