2009-12-29 47 views
55

Estoy tratando de analizar una respuesta JSON bit.ly en javscript.Analizando JSON desde XmlHttpRequest.responseJSON

Obtengo el JSON a través de XmlHttpRequest.

var req = new XMLHttpRequest; 
req.overrideMimeType("application/json"); 
req.open('GET', BITLY_CREATE_API + encodeURIComponent(url) 
      + BITLY_API_LOGIN, true); 
var target = this; 
req.onload = function() {target.parseJSON(req, url)}; 
req.send(null); 

parseJSON: function(req, url) { 
if (req.status == 200) { 
    var jsonResponse = req.responseJSON; 
    var bitlyUrl = jsonResponse.results[url].shortUrl; 
} 

Lo hago en un complemento de Firefox. Cuando corro, aparece el error "jsonResponse no está definido" para la línea var bitlyUrl = jsonResponse.results[url].shortUrl;. ¿Estoy haciendo algo mal al analizar JSON aquí? ¿O qué está mal con este código?

Respuesta

156

Nuevas formas I: fetch

TL; DR lo recomiendo esta manera, siempre y cuando no tenga que enviar solicitudes sincrónicas o apoyar los navegadores antiguos.

Mientras su solicitud sea asincrónica, puede usar el Fetch API para enviar solicitudes HTTP. La API de recuperación funciona con promises, que es una buena manera de manejar flujos de trabajo asíncronos en JavaScript. Con este enfoque se utiliza fetch() para enviar una petición y ResponseBody.json() a analizar la respuesta:

fetch(url) 
    .then(function(response) { 
    return response.json(); 
    }) 
    .then(function(jsonResponse) { 
    // do something with jsonResponse 
    }); 

Compatibilidad: El Fetch API no es compatible con IE11, así como Edge 12 & 13. Sin embargo, hay polyfills.

Nuevas formas II: responseType

Como Londeren ha escrito en his answer, los nuevos navegadores le permiten utilizar la propiedad responseType para definir el formato esperado de la respuesta. Los datos de respuesta analizados se puede acceder entonces a través de la propiedad response:

var req = new XMLHttpRequest(); 
req.responseType = 'json'; 
req.open('GET', url, true); 
req.onload = function() { 
    var jsonResponse = req.response; 
    // do something with jsonResponse 
}; 
req.send(null); 

Compatibilidad: responseType = 'json' no está soportado por EI11.

La manera clásica

El estándar XMLHttpRequest no tiene responseJSON propiedad, simplemente responseText y responseXML. Mientras bitly realmente responde con un poco de JSON a su solicitud, responseText debe contener el código JSON como texto, por lo que todo lo que tienes que hacer es analizarlo con JSON.parse():

var req = new XMLHttpRequest(); 
req.overrideMimeType("application/json"); 
req.open('GET', url, true); 
req.onload = function() { 
    var jsonResponse = JSON.parse(req.responseText); 
    // do something with jsonResponse 
}; 
req.send(null); 

Compatibilidad: Este enfoque debe funciona con cualquier navegador que admita XMLHttpRequest y JSON.

JSONHttpRequest

Si prefiere utilizar responseJSON, pero desea una solución más ligero que JQuery, es posible que desee comprobar hacia fuera mi JSONHttpRequest. Funciona exactamente como una XMLHttpRequest normal, pero también proporciona la propiedad responseJSON. Todo lo que tiene que cambiar en su código sería la primera línea:

var req = new JSONHttpRequest(); 

JSONHttpRequest también proporciona funcionalidad para enviar fácilmente los objetos JavaScript como JSON. Más detalles y el código se puede encontrar aquí: http://pixelsvsbytes.com/2011/12/teach-your-xmlhttprequest-some-json/.

Descripción completa: Soy el propietario de Pixels | Bytes. Creo que mi script es una buena solución al problema, así que lo publiqué aquí. Por favor, deja un comentario, si quieres que elimine el enlace.

+1

pixelsvsbytes.com realmente vale la pena leer – CapelliC

+3

+1; IMO esta fue la respuesta real a la pregunta - no jQuery simplemente viejo vainilla '' 'XMLHttpRequest'''; De qué se trataba la pregunta. –

+0

También hay una versión de jquery. Si está obteniendo problemas con los navegadores cruzados, pruébelo, por lo general los problemas del framework son los siguientes: http://api.jquery.com/jquery.parsejson/ – sagits

2

Creo que debe incluir jQuery para usar responseJSON.

Sin jQuery, puede probar con responseText y tratar como eval("("+req.responseText+")");

ACTUALIZACIÓN: Por favor leer el comentario con respecto a eval, puede probar con eval, pero no lo uso en la extensión del trabajo.

O

uso json_parse: no utiliza eval

+4

Para un complemento de Firefox corriendo con privs cromo, no trate de eval nada que se obtiene de un afuera fuente. En su lugar, use JSON.parse (al menos en FF 3.5 y posterior). –

0

Uso nsIJSON si esto es para una extensión FF:

var req = new XMLHttpRequest; 
req.overrideMimeType("application/json"); 
req.open('GET', BITLY_CREATE_API + encodeURIComponent(url) + BITLY_API_LOGIN, true); 
var target = this; 
req.onload = function() {target.parseJSON(req, url)}; 
req.send(null); 

parseJSON: function(req, url) { 
if (req.status == 200) { 
    var jsonResponse = Components.classes["@mozilla.org/dom/json;1"] 
     .createInstance(Components.interfaces.nsIJSON.decode(req.responseText); 
    var bitlyUrl = jsonResponse.results[url].shortUrl; 
} 

Para una página web, sólo tiene que utilizar JSON.parse en lugar de Components.classes["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON.decode

2

Nota: Solo he probado esto en Chrome.

que añade una función prototipo a la XMLHttpRequest .. XHR2,

en XHR 1 es probable que sólo necesitan para reemplazar this.response con this.responseText

Object.defineProperty(XMLHttpRequest.prototype,'responseJSON',{value:function(){ 
return JSON.parse(this.response); 
},writable:false,enumerable:false}); 

para devolver el JSON en XHR2

xhr.onload=function(){ 
console.log(this.responseJSON()); 
} 

EDIT

Si va a utilizar XHR con arraybuffer u otros tipos de respuesta, debe verificar si la respuesta es string.

En cualquier caso, debe agregar más comprobaciones, p. si no puede analizar el json.

Object.defineProperty(XMLHttpRequest.prototype,'responseJSON',{value:function(){ 
return (typeof this.response==='string'?JSON.parse(this.response):this.response); 
},writable:false,enumerable:false}); 
+0

Definiría un [getter] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get) en lugar de un atributo de función si fuera usted. Simplemente reemplace 'value' con' get' en el objeto pasado a 'Object.defineProperty', y puede usar' responseJSON' como lo haría con cualquier otra variable de respuesta. – wizzwizz4

4

puede simplemente establecer xhr.responseType = 'json';

const xhr = new XMLHttpRequest(); 
 
xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1'); 
 
xhr.responseType = 'json'; 
 
xhr.onload = function(e) { 
 
    if (this.status == 200) { 
 
    console.log('response', this.response); // JSON response 
 
    } 
 
}; 
 
xhr.send(); 
 

Documentation for responseType

Cuestiones relacionadas