Parsarea JSON din XmlHttpRequest.responseJSON (Programare, Javascript, Json, Firefox Addon, Bit.Ly)

chanux a intrebat.

Încerc să analizez un răspuns bit.ly JSON în javascript.

Primesc JSON-ul prin 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;  
}

Fac acest lucru într-un addon pentru Firefox. Când execut primesc eroarea „jsonResponse is undefined” pentru linia var bitlyUrl = jsonResponse.results[url].shortUrl;. Fac ceva greșit în analizarea JSON aici? Sau ce este în neregulă cu acest cod?

5 răspunsuri
Torben

Noi modalități I: fetch

TL;DR Aș recomanda acest mod atâta timp cât nu trebuie să trimiteți cereri sincrone sau să suportați browsere vechi.

Atâta timp cât cererea este asincronă, puteți folosi Fetch API pentru a trimite cereri HTTP. Fetch API funcționează cu promisiuni, , care este o modalitate frumoasă de a gestiona fluxurile de lucru asincrone în JavaScript. Cu această abordare, utilizați fetch() pentru a trimite o cerere și ResponseBody.json() pentru a analiza răspunsul:

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

Compatibilitate: Fetch API nu este suportat de IE11, precum și de Edge 12 & 13. Cu toate acestea, există polyfills.

Noi modalități II: responseType

După cum a scris Londeren în răspunsul său, browserele mai noi vă permit să utilizați responseType pentru a defini formatul așteptat al răspunsului. Datele de răspuns analizate pot fi apoi accesate prin intermediul proprietății response proprietate:

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

Compatibilitate: responseType = 'json' nu este acceptat de IE11.

Modul clasic

Cererea XMLHttpRequest standard nu are responseJSON ci doar responseText și responseXML. Atâta timp cât bitly răspunde cu adevărat cu niște JSON la cererea dumneavoastră, responseText ar trebui să conțină codul JSON sub formă de text, astfel încât tot ce trebuie să faceți este să îl analizați cu 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);

Compatibilitate: Această abordare ar trebui să funcționeze cu orice browser care suportă XMLHttpRequest și JSON.

JSONHttpRequest

Dacă preferați să utilizați responseJSON, , dar doriți o soluție mai ușoară decât JQuery, ar fi bine să verificați JSONHttpRequest al meu. Acesta funcționează exact ca un XMLHttpRequest normal, dar oferă și funcția responseJSON proprietate. Tot ce trebuie să schimbați în codul dvs. ar fi prima linie:

var req = new JSONHttpRequest();

JSONHttpRequest oferă, de asemenea, funcționalitatea de a trimite cu ușurință obiecte JavaScript ca JSON. Mai multe detalii și codul pot fi găsite aici: http://pixelsvsbytes.com/2011/12/teach-your-xmlhttprequest-some-json/.

Dezvăluire completă: sunt proprietarul Pixels|Bytes. Am crezut că scriptul meu a fost o soluție bună pentru întrebarea inițială, dar este destul de depășit astăzi. Nu vă recomand să îl mai folosiți.

Comentarii

  • +1; IMO acesta a fost adevăratul răspuns la întrebare – fără jQuery, doar cu vanilie veche și simplă XMLHttpRequest; exact despre ce era vorba în întrebare. –  > Por Fergus In London.
  • Acolos a jquery version too. If you are getting crossbrowser issues încercați, de obicei framework-urile se ocupă mai bine de aceste probleme: api.jquery.com/jquery.parsejson –  > Por sagits.
  • Patru ani mai târziu și acest lucru este încă ajută oamenii. 🙂 Legătura cu blogul este în regulă IMO, deoarece este într-adevăr răspunsul complet la întrebare, cu cod de exemplu și o descărcare. Vă mulțumesc! –  > Por user1094821.
  • „Utilizați o nouă bibliotecă” nu este atât de util pe cât s-ar putea crede. –  > Por Sean Munson.
  • @GrunionShaftoe Ați putea să explicați, vă rog, ce vreți să spuneți? Nu sugerez să folosiți o nouă bibliotecă. Soluția recomandată de mine fetch este JavaScript standard. –  > Por Torben.
Londeren

Puteți seta pur și simplu xhr.responseType = 'json';

Documentație pentru responseType

Comentarii

  • Există un avertisment major aici: nici IE, nici versiunile actuale de Edge nu acceptă acest lucru (poate că Edge va accepta în sfârșit după trecerea la Chromium) –  > Por Machavity.
cocco

Notă: Am testat acest lucru doar în Chrome.

se adaugă o funcție prototip la XMLHttpRequest … XHR2,

în XHR 1 probabil că trebuie doar să înlocuiți this.response cu this.responseText

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

pentru a returna json-ul în xhr2

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

EDITARE

Dacă intenționați să utilizați XHR cu arraybuffer sau alte tipuri de răspuns, atunci trebuie să verificați dacă răspunsul este un răspuns de tip string.

în orice caz, trebuie să adăugați mai multe verificări, de exemplu, dacă nu este capabil să analizeze json.

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

Comentarii

  • Eu aș defini un getter în loc de un atribut de funcție, dacă aș fi în locul tău. Pur și simplu înlocuiți value cu get în obiectul transmis către Object.defineProperty, și puteți utiliza responseJSON ca pe orice altă variabilă de răspuns. –  > Por wizzwizz4.
TU

Cred că trebuie să includeți jQuery pentru a utiliza responseJSON.

Fără jQuery, ați putea încerca cu responseText și să încercați ca eval("("+req.responseText+")");

UPDATE:Vă rugăm să citiți comentariul referitor la eval, , puteți testa cu eval, dar nu-l utilizați în extensia de lucru.

SAU

utilizați json_parse : nu utilizează eval

Comentarii

  • Pentru un addon Firefox care rulează cu privilegii Chrome, nu încercați să evaluați nimic din ceea ce obțineți dintr-o sursă externă. În schimb, utilizați JSON.parse (cel puțin în FF 3.5 și ulterior). –  > Por Ben Combee.
erikvold

Utilizați nsIJSON dacă este vorba de o extensie 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;
}

Pentru o pagină web, utilizați doar JSON.parse în loc de Components.classes["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON.decode