JSON'u XmlHttpRequest.responseJSON'dan ayrıştırma


101

JavaScript'te bit.ly JSON yanıtını ayrıştırmaya çalışıyorum.

JSON'u XmlHttpRequest aracılığıyla alıyorum.

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

Bunu bir firefox eklentisinde yapıyorum. Çalıştırdığımda, satır için "jsonResponse tanımsız" hatası alıyorum var bitlyUrl = jsonResponse.results[url].shortUrl;. JSON'u burada ayrıştırırken yanlış bir şey yapıyor muyum? Veya bu kodun nesi var?

Yanıtlar:


231

Yeni yöntemler: fetch

TL; DR Eşzamanlı istekler göndermeniz veya eski tarayıcıları desteklemeniz gerekmediği sürece bu yolu öneririm.

İsteğiniz eşzamansız olduğu sürece, HTTP istekleri göndermek için Getirme API'sını kullanabilirsiniz. Getirme API'si , JavaScript'te eşzamansız iş akışlarını yönetmenin güzel bir yolu olan vaatlerle çalışır . Bu yaklaşımla, fetch()bir istek göndermek ve ResponseBody.json()yanıtı ayrıştırmak için kullanırsınız:

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

Uyumluluk: Getir API IE11 gibi Kenar 12 ve 13. Bununla beraber, orada tarafından desteklenmeyen polyfills .

Yeni yollar II: responseType

As Londeren yazılmış olan onun cevabı , yeni tarayıcıları kullanmasına izin responseTypeyanıtın beklendiği biçimini tanımlamak için özellik. Ayrıştırılan yanıt verilerine daha sonra responseözellik aracılığıyla erişilebilir :

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

Uyumluluk: responseType = 'json'IE11 tarafından desteklenmez.

Klasik yol

Standart XMLHttpRequest'in özelliği yoktur responseJSON, sadece responseTextve responseXML. İsteğinize biraz JSON ile gerçekten yanıt verdiği sürece responseText, JSON kodunu metin olarak içermelidir, bu nedenle tek yapmanız gereken onu şu şekilde ayrıştırmaktır 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);

Uyumluluk: Bu yaklaşım, XMLHttpRequestve destekleyen herhangi bir tarayıcıyla çalışmalıdır JSON.

JSONHttpRequest

responseJSONKullanmayı tercih ediyor , ancak JQuery'den daha hafif bir çözüm istiyorsanız, JSONHttpRequest'ime göz atmak isteyebilirsiniz. Tam olarak normal bir XMLHttpRequest gibi çalışır, ancak responseJSONözelliği de sağlar . Kodunuzda değiştirmeniz gereken tek şey ilk satır olacaktır:

var req = new JSONHttpRequest();

JSONHttpRequest ayrıca JavaScript nesnelerini JSON olarak kolayca göndermek için işlevsellik sağlar. Daha fazla ayrıntı ve kod burada bulunabilir: http://pixelsvsbytes.com/2011/12/teach-your-xmlhttprequest-some-json/ .

Tam açıklama: Pixels | Bytes'ın sahibiyim. Senaryomun soruna iyi bir çözüm olduğunu düşünüyorum, bu yüzden buraya gönderdim. Bağlantıyı kaldırmamı istiyorsanız lütfen bir yorum bırakın.


5
+1; IMO Bu sorunun gerçek cevabıydı - jQuery yok, sadece sade eski vanilya XMLHttpRequest; tam olarak sorunun ne hakkındaydı.
Fergus Londra'da

Orada s a jquery version too. If you are getting crossbrowser issue: Genellikle framework`s daha iyi bu sorunların üstesinden, deneyin s api.jquery.com/jquery.parsejson
sagits

1
Dört yıl sonra ve bu hala insanlara yardım ediyor. :) Örnek kod ve indirme ile soruya tam cevap olduğu için bloga bağlantı vermek iyi bir IMO'dur. Teşekkür ederim!
user1094821

"Yeni bir kitaplık kullanın" sandığı kadar yararlı değildir.
Sean Munson

@GrunionShaftoe Lütfen açıklar mısınız, ne anlama geliyor? Yeni bir kitaplık kullanmayı önermiyorum. Önerilen çözümüm fetchstandart JavaScript.
Torben

25

Basitçe ayarlayabilirsiniz 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();
  

ResponseType için belgeler


Burada büyük bir uyarı var: ne IE ne de mevcut Edge sürümleri bunu desteklemiyor (belki Edge Chromium'a geçtikten sonra nihayet destekleyecek)
Machavity

3

Not: Bunu yalnızca Chrome'da test ettim.

XMLHttpRequest'e bir prototip işlevi ekler .. XHR2 ,

içinde XHR'nin 1 muhtemelen sadece değiştirmeniz gerekiyor this.responseilethis.responseText

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

xhr2'de json'u döndürmek için

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

DÜZENLE

XHR'yi arraybufferveya başka yanıt türleriyle kullanmayı planlıyorsanız , yanıtın bir string.

her durumda, örneğin, json'u ayrıştıramazsa, daha fazla kontrol eklemeniz gerekir.

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

2
Yerinde olsam işlev özelliği yerine alıcı tanımlardım . Sadece iletilen nesnede valueile değiştirin ve diğer herhangi bir yanıt değişkeninde olduğu gibi kullanabilirsiniz . getObject.definePropertyresponseJSON
wizzwizz4

1

Kullanmak için jQuery eklemeniz gerektiğini düşünüyorum responseJSON.

JQuery olmadan responseText ile deneyebilir ve eval("("+req.responseText+")");

GÜNCELLEME : Lütfen ilgili yorumu okuyun, evaleval ile test edebilirsiniz, ancak çalışma uzantısında kullanmayın.

VEYA

json_parse kullanın : kullanmazeval


5
Chrome ayrıcalıklarıyla çalışan bir Firefox eklentisi için, dış kaynaktan aldığınız hiçbir şeyi değerlendirmeye çalışmayın. Bunun yerine JSON.parse kullanın (en azından FF 3.5 ve sonrasında).
Ben Combee

1

Bu bir FF uzantısı içinse nsIJSON kullanın :

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

Bir web sayfası için JSON.parsebunun yerine kullanınComponents.classes["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON.decode

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.