web-dev-qa-db-ja.com

XmlHttpRequest.responseJSONからJSONを解析する

Javscriptでbit.ly JSON応答を解析しようとしています。

XmlHttpRequest経由でJSONを取得します。

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

これは、Firefoxアドオンで行います。実行すると、var bitlyUrl = jsonResponse.results[url].shortUrl;行に対して「jsonResponse is undefined」というエラーが表示されます。ここでJSONの解析で何か間違ったことをしていますか?または、このコードの何が問題になっていますか?

79
chanux

新しい方法I:fetch

TL; DRあなたがいる限り、この方法をお勧めします同期リクエストを送信したり、古いブラウザをサポートしたりする必要はありません。

リクエストが非同期である限り、 Fetch API を使用してHTTPリクエストを送信できます。 fetch APIは promises で動作します。これはJavaScriptで非同期ワークフローを処理する良い方法です。このアプローチでは、fetch()を使用して要求を送信し、ResponseBody.json()を使用して応答を解析します。

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

互換性:Fetch APIは、IE 12とEdge 12および13ではサポートされていません。ただし、 polyfillsがあります。

新しい方法II:responseType

Londerenhis answer に記述しているように、新しいブラウザではresponseTypeプロパティを使用して、予期される応答の形式を定義できます。解析された応答データには、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);

互換性:responseType = 'json'はIE11でサポートされていません。

古典的な方法

標準のXMLHttpRequestにはresponseJSONプロパティはなく、responseTextresponseXMLのみがあります。リクエストに対して少しだけJSONで実際に応答する限り、responseTextにはテキストとしてJSONコードを含める必要があるため、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);

互換性:このアプローチは、XMLHttpRequestおよびJSONをサポートするすべてのブラウザーで動作するはずです。

JSONHttpRequest

responseJSONを使用したいが、JQueryよりも軽量なソリューションが必要な場合は、JSONHttpRequestを確認してください。通常のXMLHttpRequestとまったく同じように機能しますが、responseJSONプロパティも提供します。コードで変更する必要があるのは、最初の行だけです。

var req = new JSONHttpRequest();

JSONHttpRequestは、JavaScriptオブジェクトをJSONとして簡単に送信する機能も提供します。詳細とコードはここにあります: http://pixelsvsbytes.com/2011/12/teach-your-xmlhttprequest-some-json/

完全開示:私はPixels | Bytesの所有者です。私のスクリプトは問題の良い解決策だと思うので、ここに投稿しました。リンクを削除したい場合は、コメントを残してください。

198
Torben

単純に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のドキュメント

14
Londeren

注:これはChromeでのみテストしました。

xMLHttpRequestにプロトタイプ関数を追加します。XHR2

XHR 1では、おそらくthis.responsethis.responseTextに置き換えるだけです。

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

jhrをxhr2に返す

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

編集

arraybufferまたは他の応答タイプでXHRを使用する場合、応答がstringであるかどうかを確認する必要があります。

いずれの場合でも、さらにチェックを追加する必要があります。 JSONを解析できない場合。

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

responseJSONを使用するには、jQueryを含める必要があると思います。

JQueryがなければ、responseTextを試してeval("("+req.responseText+")");のように試すことができます

UPDATEevalに関するコメントを読んでください。evalでテストできますが、機能拡張では使用しないでください。

OR

use json_parseevalは使用しません

2
YOU

これがFF拡張の場合 nsIJSON を使用します。

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

ウェブページの場合は、JSON.parseの代わりにComponents.classes["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON.decodeを使用します

1
erikvold