2012-05-16 11 views
9

Zrobiłem kilka testów dzisiaj związanych ze sposobem, w jaki możemy załadować pliki json z d3, ponieważ zaintrygowało mnie to pytanie: d3.json works but $.getJson fails. Jednak niektóre z testów, które zrobiłem, są trochę trudne.Problemy z d3.json, d3.xhr i między domenami

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

wiem, że problem może być związany z co najmniej 2 powodów: typ MIME i CORS, ale nie mogę zrozumieć kilku innymi:

  1. jeżeli zwrotna jest zawsze wykonywany (nawet trudne z OK 200, które może być również błędem, jak widać z metod jQuery .ajax() i .getJSON(), dlaczego mogę zobaczyć dane tylko w jednym przypadku (pierwszy) - pozostałe są zawsze błędy?

  2. jakie są typy MIME obsługiwane metodą d3.xhr?

  3. Jeśli d3.json był po prostu ładnym opakowaniem dla d3.xhr, dlaczego przykład 1 działa, a przykład 2 nie działa ...? Chciałbym wyjaśnienia. Najczęściej używam d3 z plikami z mojego serwera, ale zdarzają się takie przypadki, kiedy muszę też używać zewnętrznych danych i byłoby miło zrobić to również z D3, nie tylko z jQuery.

Myślę, że powinna istnieć lista wszystkich typów MIME akceptowanych przez te metody.

+0

mój powód do zadawania tego jest prosty: będziemy używać do D3 mocno powiązanych wizualizacji danych w kolejnych miesiącach – paxRoman

Odpowiedz

12

Powodem, dla którego pierwsze żądanie się powiedzie, a drugie nie, dotyczy konfiguracji serwera dbpedia.org. Funkcja d3.json() robi dwie rzeczy:

  1. To ustawia nagłówek Accept do typu MIME application/json

  2. Analizuje odpowiedź korzystając JSON.parse()

Numer 1 jest problem - w dbpedia. Serwer org zwraca odpowiedź w postaci 406 (Unacceptable) dla nagłówka Accept: application/json. Nie jestem pewien, dlaczego tak jest, ale biorąc pod uwagę parametry adresu URL, które wysyłasz, wygląda na to, że serwer oczekuje zamiast tego application/sparql-results+json - w rzeczywistości podanie tego typu mime z d3.xhr() powiedzie się, a użycie application/json nie powiedzie się.

W przypadku danych Banku Światowego żądanie nie powiedzie się, ponieważ serwer nie jest CORS-enabled. Jedynym sposobem na wywołanie w przeglądarce zdalnego interfejsu API bez włączonego CORS jest użycie JSONP (zakładając, że API to obsługuje). Tak się składa, że ​​data.worldbank.com does support JSONP, ale D3 tego nie robi - musisz sam sobie z tym poradzić lub użyć biblioteki innej firmy, na przykład jQuery, aby wysłać żądanie.

Ogólnie rzecz biorąc, D3 nie nadał priorytetu naprawdę solidnej obsłudze AJAX w sposób, w jaki jQuery i inne biblioteki mają, ponieważ to nie jest jej celem - więc jeśli chcesz załadować wiele różnych zasobów zewnętrznych, prawdopodobnie powinieneś to zrobić za pomocą Zewnętrzna biblioteka, która ma więcej wsparcia dla starannie zmodyfikowanych wywołań AJAX. W zależności od tego, co chcesz załadować, inną opcją jest skonfigurowanie serwera proxy na własnym serwerze, który może wywoływać zdalne interfejsy API, a następnie przekazywać dane do wizualizacji za pośrednictwem lokalnego wywołania HTTP - w takim przypadku wszystkie ładowarki D3 powinny dobrze pracować.

+1

Dla WorldBank, polecam za pomocą [wtyczka d3.jsonp] (https://github.com/d3/d3-plugins/tree/master/jsonp). Będziesz jednak chciał go zmodyfikować, aby pracować z [strukturą połączeń WorldBank] (http://data.worldbank.org/node/11). Struktura wywołania używa ciągu zapytania url '& prefix = callbackFunctionName' do określenia funkcji wywołania zwrotnego, podczas gdy wtyczka d3.jsonp oczekuje' & callback = nazwaFunkcji wywołania'. Możesz więc zmienić wiersze 10 i 24, zastępując słowo "oddzwanianie" za pomocą 'przedrostka' (patrz [to pastebin] (http://pastebin.com/MLs0LaKW)). Następnie utwórz funkcję zwrotną, która zostanie wykonana w odpowiedzi. – wgardiner

0

Problematyczne Przykład 1 brakuje otwór nawias klamrowy pomiędzy

funkcja "(data)" i "konsola".

To działa na mnie raz przepisany jako function(data) { console itp

Powiązane problemy