javascript - Parsning av JSON från XmlHttpRequest.responseJSON
Jag försöker tolka ett bit.ly JSON-svar i JavaScript.
Jag får 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;
}
Jag gör detta i ett Firefox-tillägg. När jag kör får jag felet "jsonResponse är odefinierad" för raden var bitlyUrl=jsonResponse.results[url].shortUrl;. Gör jag något fel när jag tolkar JSON här? Eller vad är fel med denna kod?
Svar #1
Nya sätt I: fetch
TL;DR Jag skulle rekommendera detta sätt så länge du inte behöver skicka synkrona förfrågningar eller stödja gamla webbläsare.
Så länge din förfrågan är asynkron kan du använda Fetch API för att skicka HTTP-förfrågningar. Fetch API fungerar med promises, vilket är ett bra sätt att hantera asynkrona arbetsflöden i JavaScript. Med detta tillvägagångssätt använder du fetch() för att skicka en förfrågan och ResponseBody.json() för att analysera svaret:
fetch(url)
.then(function(response) {
return response.json();
})
.then(function(jsonResponse) {
// do something with jsonResponse
});
Du kan använda await-satsen istället för promise-notationen för att hålla koden läsbar:
const response = await fetch(url);
const jsonResponse = await response.json();
// do something with jsonResponse
Kompatibilitet: Fetch API stöds inte av IE11 samt Edge 12 & 13. Det finns dock polyfiller.
Nya sätt II: responseType
Som Londeren har skrivit i sitt svar, tillåter nyare webbläsare dig att använda responseType-egenskapen för att definiera det förväntade formatet på svaret. De tolkade svarsdata kan sedan nås via response-egenskapen:
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);
Kompatibilitet: responseType='json' stöds inte av IE11.
Det klassiska sättet
Den standardmässiga XMLHttpRequest har ingen responseJSON-egenskap, bara responseText och responseXML. Så länge bitly verkligen svarar med någon JSON på din förfrågan, bör responseText innehålla JSON-koden som text, så allt du behöver göra är att tolka den med 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);
Kompatibilitet: Detta tillvägagångssätt bör fungera med alla webbläsare som stöder XMLHttpRequest och JSON.
JSONHttpRequest
Upplysning: Jag är ägare till Pixels|Bytes. Jag trodde att mitt skript var en bra lösning på den ursprungliga frågan, men det är ganska föråldrat idag. Jag rekommenderar inte att använda det längre.
Om du föredrar att använda responseJSON, men vill ha en mer lättviktig lösning än JQuery, kanske du vill kolla in min JSONHttpRequest. Den fungerar precis som en vanlig XMLHttpRequest, men tillhandahåller också egenskapen responseJSON. Allt du behöver ändra i din kod skulle vara den första raden:
var req = new JSONHttpRequest();
JSONHttpRequest tillhandahåller också funktionalitet för att enkelt skicka JavaScript-objekt som JSON. Mer information och koden kan hittas här: http://pixelsvsbytes.com/2011/12/teach-your-xmlhttprequest-some-json/.
Svar #2
Du kan helt enkelt sätta 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();
Dokumentation för responseType
