Analizando JSON desde XMLHttpRequest.Responder
Estoy tratando de analizar un bit.ly Respuesta JSON en javscript.
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;
}
Hago esto en un complemento de Firefox. Cuando corro obtengo el error "JsonResponse is undefined" para la línea var bitlyUrl = jsonResponse.results[url].shortUrl;
. ¿Estoy haciendo algo malo al analizar JSON aquí? ¿O qué tiene de malo este código?
5 answers
Nuevas formas I: fetch
TL; DR Lo recomendaría de esta manera, siempre y cuando no tenga que enviar solicitudes síncronas o admitir navegadores antiguos.
A mientras su solicitud sea asíncrona, puede usar la API Fetch para enviar solicitudes HTTP. La API fetch 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 solicitud y ResponseBody.json()
para analizar el respuesta:
fetch(url)
.then(function(response) {
return response.json();
})
.then(function(jsonResponse) {
// do something with jsonResponse
});
Compatibilidad: La API Fetch no es compatible con IE11 ni con Edge 12 y 13. Sin embargo, hay polyfills.
Nuevos caminos II: responseType
Como Londeren ha escrito en su respuesta, los navegadores más nuevos le permiten usar la propiedad responseType
para definir el formato esperado de la respuesta. Se puede acceder a los datos de respuesta analizados 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 es compatible con IE11.
La forma clásica
El estándar XMLHttpRequest no tiene ninguna propiedad responseJSON
, solo responseText
y responseXML
. Mientras bitly realmente responda con algo de JSON a tu solicitud, responseText
debería contener el código JSON como texto, así 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 debería funcionar con cualquier navegador que soporte XMLHttpRequest
y JSON
.
JSONHttpRequest
Si prefiere usar responseJSON
, pero desea una solución más ligera que jQuery, es posible que desee revisar mi JSONHttpRequest. Funciona exactamente como un XMLHttpRequest normal, pero también proporciona la propiedad responseJSON
. Todo lo que tienes que cambiar en tu código sería la primera línea:
var req = new JSONHttpRequest();
JSONHttpRequest también proporciona funcionalidad para enviar fácilmente objetos JavaScript como JSON. Más detalles y el código se pueden encontrar aquí: http://pixelsvsbytes.com/2011/12/teach-your-xmlhttprequest-some-json/.
Revelación completa: Soy el dueño de Pixels / Bytes. Creo que mi guión es una buena solución al problema, así que lo publiqué aquí. Por favor, deja un comentario, si quieres que elimine el enlace.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-28 12:21:07
Simplemente puede configurar 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();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-27 08:27:55
Creo que tienes que incluir jQuery para usar responseJSON
.
Sin jQuery, puedes probar con responseText y probar como eval("("+req.responseText+")");
ACTUALIZAR : Por favor, lea el comentario sobre eval
, puede probar con eval, pero no lo use en la extensión de trabajo.
O
Use json_parse : no usa eval
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-29 06:39:11
Nota: Solo he probado esto en Chrome.
Añade una función prototype al XMLHttpRequest .. XHR2 ,
En XHR 1 probablemente solo necesite reemplazar this.response
por 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());
}
EDITAR
Si planea usar XHR con arraybuffer
u otros tipos de respuesta, entonces debe verificar si la respuesta es un string
.
En cualquier caso, debe agregar más comprobaciones, por ejemplo, si no es capaz de 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});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-05 02:28:35
Use 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, simplemente use JSON.parse
en lugar de Components.classes["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON.decode
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-21 06:29:13