wake-up-neo.com

Analysieren von JSON aus XmlHttpRequest.responseJSON

Ich versuche, eine kleine JSON-Antwort in javscript zu analysieren.

Ich erhalte den JSON über 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;  
}

Ich mache das in einem Firefox-Addon. Wenn ich laufe bekomme ich den Fehler "jsonResponse ist undefiniert" für die Zeile var bitlyUrl = jsonResponse.results[url].shortUrl;. Mache ich etwas falsch beim Parsen von JSON hier? Oder was ist mit diesem Code falsch?

79
chanux

Neue Wege I: fetch

TL; DR Ich würde diesen Weg empfehlen, solange Sie nicht senden müssen synchrone Anfragen oder Unterstützung alter Browser.

Solange Ihre Anfrage asynchron ist, können Sie die Fetch API verwenden, um HTTP-Anfragen zu senden. Die Fetch-API arbeitet mit Versprechen , was eine gute Möglichkeit ist, mit asynchronen Workflows in JavaScript umzugehen. Bei diesem Ansatz verwenden Sie fetch(), um eine Anforderung zu senden, und ResponseBody.json(), um die Antwort zu analysieren:

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

Kompatibilität: Die Fetch-API wird nicht von IE11 sowie von Edge 12 und 13 unterstützt. Es gibt jedoch polyfills .

Neue Wege II: responseType

Wie Londeren in seine Antwort geschrieben hat, können Sie in neueren Browsern mit der Eigenschaft responseType das erwartete Format der Antwort definieren. Auf die analysierten Antwortdaten kann dann über die Eigenschaft response zugegriffen werden:

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

Kompatibilität: responseType = 'json' Wird von IE11 nicht unterstützt.

Der klassische Weg

Der Standard XMLHttpRequest hat keine responseJSON -Eigenschaft, nur responseText und responseXML. Solange bitly wirklich mit JSON auf Ihre Anfrage antwortet, sollte responseText den JSON-Code als Text enthalten. Sie müssen ihn also nur mit JSON.parse() analysieren:

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

Kompatibilität: Dieser Ansatz sollte mit jedem Browser funktionieren, der XMLHttpRequest und JSON unterstützt.

JSONHttpRequest

Wenn Sie responseJSON bevorzugen, aber eine leichtere Lösung als JQuery wünschen, sollten Sie sich meine JSONHttpRequest ansehen. Es funktioniert genau wie ein normaler XMLHttpRequest, bietet aber auch die Eigenschaft responseJSON. Alles, was Sie in Ihrem Code ändern müssen, wäre die erste Zeile:

var req = new JSONHttpRequest();

JSONHttpRequest bietet auch Funktionen zum einfachen Senden von JavaScript-Objekten als JSON. Weitere Details und den Code finden Sie hier: http://pixelsvsbytes.com/2011/12/teach-your-xmlhttprequest-some-json/ .

Vollständige Offenlegung: Ich bin der Besitzer von Pixels | Bytes. Ich denke, mein Skript ist eine gute Lösung für das Problem, also habe ich es hier gepostet. Bitte hinterlasse einen Kommentar, wenn ich den Link entfernen soll.

198
Torben

Sie können einfach 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();
  

Dokumentation für responseType

14
Londeren

Hinweis: Ich habe dies nur in Chrome getestet.

es fügt dem XMLHttpRequest eine Prototypfunktion hinzu. XHR2,

in XHR 1 müssen Sie wahrscheinlich nur this.response durch this.responseText ersetzen.

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

um den json in xhr2 zurückzugeben

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

BEARBEITEN

Wenn Sie XHR mit arraybuffer oder anderen Antworttypen verwenden möchten, müssen Sie prüfen, ob es sich bei der Antwort um eine string handelt.

in jedem Fall müssen Sie weitere Prüfungen hinzufügen, z. wenn es nicht in der Lage ist, den JSON zu analysieren.

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

Ich denke, Sie müssen jQuery einschließen, um responseJSON zu verwenden.

Ohne jQuery könnten Sie es mit responseText versuchen und versuchen, wie eval("("+req.responseText+")");

[~ # ~] Update [~ # ~] : Bitte lesen Sie den Kommentar zu eval, den Sie mit eval testen können, aber nicht Verwenden Sie es nicht in der Arbeitserweiterung.

OR

benutze json_parse : eval wird nicht verwendet

2
YOU

Verwenden Sie nsIJSON , wenn dies für eine FF-Erweiterung gilt:

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

Verwenden Sie für eine Webseite einfach JSON.parse anstatt Components.classes["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON.decode

1
erikvold