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


Я пытаюсь разобрать немного.лы ответа JSON в контрактной работе с разными компаниями.

Я получаю 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 не определен" для строки var bitlyUrl = jsonResponse.results[url].shortUrl;. Я делаю что-то неправильно в разборе JSON здесь? Или что не так с этим кодом?

5 66

5 ответов:

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

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

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

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

совместимость: API выборки не поддерживается IE11, а также Edge 12 & 13. Тем не менее, есть полифиллы.

новые способы 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. Пока bitly действительно отвечает некоторым 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/.

полное раскрытие: я владелец пикселей / байт. Я думаю, что мой скрипт является хорошим решением проблемы, поэтому я разместил его здесь. Пожалуйста, оставьте комментарий, если вы хотите, чтобы я удалил ссылку.

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

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

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

обновление:пожалуйста, прочитайте комментарий в отношении eval, вы можете проверить с eval, но не используйте его в рабочем расширении.

или

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

примечание: Я только проверил это в 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());
}

EDIT

если вы планируете использовать 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});

использовать 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