Подтвердить что ты не робот

Разбор JSON из XmlHttpRequest.responseJSON

Я пытаюсь разобрать бит .ly ответ JSON в javscript.

Я получаю JSON через 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;  
}

Я делаю это в аддоне firefox. Когда я запускаю, я получаю сообщение об ошибке "jsonResponse undefined" для строки var bitlyUrl = jsonResponse.results[url].shortUrl;. Я делаю что-то не так в разборе JSON здесь? Или что не так с этим кодом?

4b9b3361

Ответ 1

Новые способы I: fetch

TL; DR Я бы рекомендовал этот способ, пока вам не нужно отправлять синхронные запросы или поддерживать старые браузеры.

До тех пор, пока ваш запрос будет асинхронным, вы можете использовать Fetch API для отправки HTTP-запросов. API-интерфейс fetch работает с promises, что является хорошим способом обработки асинхронных рабочих процессов в JavaScript. При таком подходе вы используете fetch() для отправки запроса и ResponseBody.json() для анализа ответа:

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

Совместимость: API-интерфейс Fetch не поддерживается IE11, а также Edge 12 и 13. Однако есть polyfills.

Новые способы II: responseType

Поскольку Londeren написал в свой ответ, новые браузеры позволяют использовать 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, только responseText и responseXML. До тех пор, пока биттово действительно отвечает некоторым 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. Я думаю, что мой script является хорошим решением проблемы, поэтому я разместил его здесь. Пожалуйста, оставьте комментарий, если вы хотите, чтобы я удалил ссылку.

Ответ 2

Вы можете просто установить 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();
  

Ответ 3

Я думаю, вы должны включить jQuery для использования responseJSON.

Без jQuery вы можете попробовать с responseText и попробовать как eval("("+req.responseText+")");

ОБНОВЛЕНИЕ. Пожалуйста, прочитайте комментарий относительно eval, вы можете протестировать с помощью eval, но не используйте его в рабочем расширении.

ИЛИ

используйте json_parse: он не использует eval

Ответ 4

Примечание. Я тестировал это только в Chrome.

он добавляет функцию прототипа в XMLHttpRequest. XHR2,

в XHR 1 вам, вероятно, просто нужно заменить this.response на this.responseText

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

чтобы вернуть json в xhr2

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

ИЗМЕНИТЬ

Если вы планируете использовать XHR с arraybuffer или другими типами ответов, вам нужно проверить, является ли ответ string.

в любом случае вам нужно добавить дополнительные проверки, например. если он не сможет разобрать json.

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

Ответ 5

Используйте nsIJSON, если это для расширения 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;
}

Для веб-страницы просто используйте JSON.parse вместо Components.classes["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON.decode