2009-12-29 13 views
55

Próbuję parsować bit.ly odpowiedź JSON w javscript.Parsowanie JSON z XmlHttpRequest.responseJSON

Otrzymuję JSON przez 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; 
} 

Robię to w dodatku firefox. Po uruchomieniu pojawia się błąd "jsonResponse jest niezdefiniowany" dla linii var bitlyUrl = jsonResponse.results[url].shortUrl;. Czy robię coś złego w analizie JSON tutaj? Lub co jest nie tak z tym kodem?

Odpowiedz

156

Nowe sposoby I: fetch

TL; DR ja polecam ten sposób tak długo, jak nie masz wysłać synchronicznych żądań lub wsparcia starych przeglądarek.

Dopóki twoje żądanie jest asynchroniczne, możesz użyć Fetch API do wysyłania żądań HTTP. Interfejs API pobierania działa z promises, co jest dobrym sposobem na obsługę asynchronicznych przepływów pracy w JavaScript. Dzięki takiemu podejściu użyć fetch() wysłać wniosek i ResponseBody.json() do analizowania odpowiedzi:

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

Kompatybilność: Fetch API nie jest obsługiwany przez IE11 oraz krawędzi 12 & 13. Jednakże istnieją polyfills.

Nowe sposoby II: responseType

Jak Londeren została napisana w his answer nowsze przeglądarek pozwalają użyć właściwości responseType zdefiniować oczekiwany format odpowiedzi. Przeanalizowane dane reakcji można następnie uzyskać za pośrednictwem właściwości 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); 

Kompatybilność: responseType = 'json' nie jest obsługiwany przez IE11.

Klasycznym sposobem

Standardowa XMLHttpRequest ma responseJSON własność, tylko responseText i responseXML. Dopóki bitly naprawdę reaguje z pewnym JSON do Państwa potrzeb, responseText powinna zawierać kod JSON jako tekst, więc wszystko co masz zrobić, to do analizowania go 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); 

Kompatybilność: Podejście to powinno działa z każdą przeglądarką obsługującą XMLHttpRequest i JSON.

JSONHttpRequest

Jeśli wolisz używać responseJSON, ale chcesz bardziej lekkie rozwiązanie niż JQuery, może chcesz sprawdzić moje JSONHttpRequest. Działa dokładnie tak, jak normalne XMLHttpRequest, ale także zapewnia właściwość responseJSON. Wszystko, co trzeba zmienić w kodzie byłaby pierwsza linia:

var req = new JSONHttpRequest(); 

JSONHttpRequest zapewnia również funkcjonalność łatwo wysyłać obiektów JavaScript jak JSON. Więcej szczegółów i kod można znaleźć tutaj: http://pixelsvsbytes.com/2011/12/teach-your-xmlhttprequest-some-json/.

Pełne ujawnienie: Jestem właścicielem Pixels | Bytes. Myślę, że mój skrypt jest dobrym rozwiązaniem problemu, dlatego opublikowałem go tutaj. Proszę zostaw komentarz, jeśli chcesz, żebym usunął link.

+1

pixelsvsbytes.com to naprawdę warto przeczytać – CapelliC

+3

+1; IMO to była prawdziwa odpowiedź na pytanie - brak jQuery to zwykły stary vanilla '' 'XMLHttpRequest'''; właśnie o co chodziło. –

+0

Istnieje również wersja jquery. Jeśli masz problem z crossbrowser, spróbuj tego lepiej: http://api.jquery.com/jquery.parsejson/ – sagits

2

Myślę, że musisz dołączyć jQuery do użycia responseJSON.

Bez jQuery, można spróbować z responseText i spróbuj jak eval("("+req.responseText+")");

UPDATE: Proszę przeczytać uwagi odnośnie eval, można przetestować z eval, ale nie należy go używać w przedłużenie pracy.

LUB

użycie json_parse: nie używa eval

+4

Na dodatek Firefox działa z chromowanymi privs, nie próbuj niczego eval można dostać z zewnątrz źródło. Zamiast tego użyj JSON.parse (przynajmniej w FF 3.5 i późniejszych). –

0

Korzystając nsIJSON jeśli jest to dla przedłużenia 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; 
} 

Na stronie internetowej, wystarczy użyć JSON.parse zamiast Components.classes["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON.decode

2

Uwaga: testowałem to tylko w Chrome.

dodaje funkcję prototypu do XMLHttpRequest .. XHR2,

w XHR 1 prawdopodobnie wystarczy zastąpić this.response z this.responseText

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

zwrotu json w xhr2

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

EDYCJA

Jeśli zamierzasz używać XHR z arraybuffer lub innymi typami odpowiedzi, musisz sprawdzić, czy odpowiedź to string.

w każdym przypadku musisz dodać więcej kontroli, np. jeśli nie jest w stanie przeanalizować jsona.

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

Chciałbym zdefiniować [getter] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get) zamiast atrybutu funkcji, gdybym był tobą. Po prostu zamień 'wartość' na' get' w obiekcie przekazanym do 'Object.defineProperty', a możesz użyć' responseJSON', tak jak każdej innej zmiennej odpowiedzi. – wizzwizz4

4

można po prostu ustawić 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