2012-05-16 26 views
9

Hice varias pruebas hoy relacionadas con la forma en que podemos cargar archivos json con d3 porque estaba intrigado con esta pregunta: d3.json works but $.getJson fails. Sin embargo, algunas de las pruebas que hice son un poco complicadas.d3.json, d3.xhr y problemas entre dominios

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

sé que el problema puede estar relacionado con al menos 2 razones: Tipo MIME y CORS, pero no puedo entender varias cosas:

  1. si la devolución de llamada se ejecuta siempre (incluso resistente a veces con el OK 200, que también puede ser un error como se ve en los métodos .ajax() y .getJSON() de jQuery. ¿Por qué puedo ver los datos en un solo caso (el primero)? El resto de los casos son siempre errores?

  2. ¿Cuáles son los tipos MIME compatibles con el método d3.xhr?

  3. si d3.json era solo un buen contenedor para d3.xhr ¿por qué funciona el ejemplo 1 y el ejemplo 2 no funciona ...? Me gustaría alguna aclaración. Uso principalmente d3 con archivos de mi servidor, pero hay casos como este cuando también tengo que usar algunos datos externos, y sería muy bueno hacer esto también con D3, no solo con jQuery.

Creo que debería haber una lista con todos los tipos MIME aceptados por estos métodos.

+0

mi razón de hacer esto es simple: vamos a utilizar en gran medida D3 para visualizaciones de datos vinculados en los próximos meses – paxRoman

Respuesta

12

La razón por la cual la primera solicitud tiene éxito mientras que la segunda falla tiene que ver con una configuración del servidor de dbpedia.org. La función d3.json() hace dos cosas:

  1. Se establece la cabecera Accept para el tipo MIME application/json

  2. Se analiza la respuesta utilizando JSON.parse()

El número 1 es el tema - la DBpedia. el servidor org está devolviendo una respuesta de 406 (Unacceptable) para el encabezado Accept: application/json. No estoy seguro de por qué esto es cierto, pero teniendo en cuenta los parámetros de URL que está enviando, parece que el servidor espera application/sparql-results+json en su lugar; de hecho, al especificar este tipo mime con d3.xhr() se produce un error, mientras que application/json falla.

Con los datos del Banco Mundial, la solicitud falla porque el servidor no es CORS-enabled. La única forma en el navegador para realizar una llamada a una API remota sin CORS habilitado es usar JSONP (suponiendo que la API lo admita). Da la casualidad, data.worldbank.com does support JSONP, pero D3 no lo hace; deberá tratarlo usted mismo o utilizar una biblioteca de terceros como jQuery para realizar la solicitud.

En general, D3 no ha dado prioridad muy robusto soporte AJAX la forma en que jQuery y otras bibliotecas tienen, porque ese no es su enfoque - por lo que si desea cargar una amplia variedad de recursos externos, probablemente debería hacerlo con una Biblioteca de terceros que tiene más soporte para llamadas AJAX cuidadosamente ajustadas. Dependiendo de lo que desee cargar, la otra opción es configurar un proxy en su propio servidor que pueda llamar a las API remotas y luego devolver los datos a sus visualizaciones a través de una llamada HTTP local, en cuyo caso deben cargarse todos los cargadores de D3. trabaja bien.

+1

Para WorldBank, me gustaría sugerir el uso de la [complemento d3.jsonp] (https://github.com/d3/d3-plugins/tree/master/jsonp). Sin embargo, querrá modificarlo para trabajar con la [estructura de llamadas de WorldBank] (http://data.worldbank.org/node/11). La estructura de llamada utiliza la cadena de consulta url '& prefix = callbackFunctionName' para especificar la función de devolución de llamada, mientras que el complemento d3.jsonp espera' & callback = callbackFunctionName'. Así que puede cambiar las líneas 10 y 24, reemplazando la palabra 'callback' por' prefix' (vea [this pastebin] (http://pastebin.com/MLs0LaKW)). A continuación, cree una función de devolución de llamada que se ejecutará en la respuesta. – wgardiner

0

ejemplo Problemática 1 le falta un llave de apertura entre

"función (datos)" y "consola".

funciona para mí una vez reescrito como function(data) { console etc.