Pesquisa de site

javascript - Analisando JSON de XmlHttpRequest.responseJSON


Estou tentando analisar uma resposta JSON do bit.ly em javascript.

Eu obtenho o JSON via 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;  
}

Eu faço isso em um addon do Firefox. Quando executo, recebo o erro "jsonResponse is undefined" na linha var bitlyUrl=jsonResponse.results[url].shortUrl;. Estou fazendo algo errado ao analisar o JSON aqui? Ou o que há de errado com este código?

Resposta #1

Novas formas I: fetch

TL;DR Eu recomendaria este método contanto que você não precise enviar requisições síncronas ou suportar navegadores antigos.

Enquanto sua solicitação for assíncrona, você pode usar a API Fetch para enviar requisições HTTP. A API fetch funciona com promises, que é uma maneira agradável de lidar com fluxos de trabalho assíncronos em JavaScript. Com essa abordagem, você usa fetch() para enviar uma solicitação e ResponseBody.json() para analisar a resposta:

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

Você pode usar a instrução await em vez da notação de promessa, para manter o código legível:

const response = await fetch(url);
const jsonResponse = await response.json();
// do something with jsonResponse

Compatibilidade: A API Fetch não é suportada pelo IE11, assim como pelo Edge 12 e 13. No entanto, existem polyfills.

Novas maneiras II: responseType

Como Londeren escreveu em sua resposta, navegadores mais recentes permitem que você use a propriedade responseType para definir o formato esperado da resposta. Os dados da resposta analisada podem então ser acessados através da propriedade 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);

Compatibilidade: responseType='json' não é suportado pelo IE11.

O jeito clássico

O XMLHttpRequest padrão não possui a propriedade responseJSON, apenas responseText e responseXML. Contanto que o bitly realmente responda com algum JSON à sua solicitação, responseText deve conter o código JSON como texto, então tudo o que você precisa fazer é analisá-lo com 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);

Compatibilidade: Esta abordagem deve funcionar com qualquer navegador que suporte XMLHttpRequest e JSON.

JSONHttpRequest

Divulgação: Eu sou o proprietário da Pixels|Bytes. Eu achei que meu script era uma boa solução para a pergunta original, mas ele está bastante desatualizado hoje. Não recomendo mais usá-lo.

Se você preferir usar responseJSON, mas quiser uma solução mais leve do que JQuery, você pode querer dar uma olhada no meu JSONHttpRequest. Ele funciona exatamente como um XMLHttpRequest normal, mas também fornece a propriedade responseJSON. Tudo o que você precisa mudar no seu código seria a primeira linha:

var req = new JSONHttpRequest();

JSONHttpRequest também oferece funcionalidade para enviar facilmente objetos JavaScript como JSON. Mais detalhes e o código podem ser encontrados aqui: http://pixelsvsbytes.com/2011/12/teach-your-xmlhttprequest-some-json/.

Resposta #2

Você pode simplesmente definir 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();
  

Documentação para responseType

Artigos relacionados