J'essaie d'analyser un peu la réponse JSON en javscript.
Je reçois le 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;
}
Je le fais dans un addon firefox. Quand j’exécute, l’erreur "jsonResponse est indéfinie" apparaît pour la ligne var bitlyUrl = jsonResponse.results[url].shortUrl;
. Est-ce que je fais quelque chose de mal en analysant JSON ici? Ou ce qui ne va pas avec ce code?
Nouvelles manières I: fetch
TL; DR Je le recommanderais si vous n'avez pas à envoyer de message. requêtes synchrones ou supporte les anciens navigateurs.
Tant que votre demande est asynchrone, vous pouvez utiliser le Fetch API pour envoyer des requêtes HTTP. L'API d'extraction fonctionne avec promises , qui est un moyen agréable de gérer les flux de travail asynchrones en JavaScript. Avec cette approche, vous utilisez fetch()
pour envoyer une demande et ResponseBody.json()
pour analyser la réponse:
fetch(url)
.then(function(response) {
return response.json();
})
.then(function(jsonResponse) {
// do something with jsonResponse
});
Compatibilité: L'API Fetch n'est pas pris en charge par IE11 ni par Edge 12 & 13. Cependant, il existe polyfills .
Nouvelles manières II: responseType
Comme Londeren a écrit sa réponse , les nouveaux navigateurs vous permettent d'utiliser la propriété responseType
pour définir le format attendu de la réponse. Les données de réponse analysées sont ensuite accessibles via la propriété 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);
Compatibilité: responseType = 'json'
N'est pas supporté par IE11.
La méthode classique
Le XMLHttpRequest standard n'a pas de propriété responseJSON
, juste responseText
et responseXML
. Tant que bitly répond vraiment avec du JSON à votre requête, responseText
devrait contenir le code JSON sous forme de texte. Tout ce que vous avez à faire est de l'analyser avec 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);
Compatibilité: cette approche devrait fonctionner avec tout navigateur prenant en charge XMLHttpRequest
et JSON
.
JSONHttpRequest
Si vous préférez utiliser responseJSON
, mais souhaitez une solution plus légère que JQuery, vous pouvez consulter ma requête JSONHttpRequest. Il fonctionne exactement comme un XMLHttpRequest normal, mais fournit également la propriété responseJSON
. Tout ce que vous avez à changer dans votre code serait la première ligne:
var req = new JSONHttpRequest();
JSONHttpRequest fournit également une fonctionnalité permettant d'envoyer facilement des objets JavaScript au format JSON. Plus de détails et le code peuvent être trouvés ici: http://pixelsvsbytes.com/2011/12/teach-your-xmlhttprequest-some-json/ .
Divulgation complète: je suis le propriétaire de Pixels | Bytes. Je pense que mon script est une bonne solution au problème, alors je l'ai posté ici. S'il vous plaît laissez un commentaire, si vous voulez que je supprime le lien.
Vous pouvez simplement définir 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();
Remarque: je n'ai testé cela que dans Chrome.
il ajoute une fonction prototype à XMLHttpRequest .. XHR2,
dans XHR 1 il vous suffit probablement de remplacer this.response
avec this.responseText
Object.defineProperty(XMLHttpRequest.prototype,'responseJSON',{value:function(){
return JSON.parse(this.response);
},writable:false,enumerable:false});
retourner le json en xhr2
xhr.onload=function(){
console.log(this.responseJSON());
}
MODIFIER
Si vous envisagez d'utiliser XHR avec arraybuffer
ou d'autres types de réponses, vous devez vérifier si la réponse est un string
.
dans tous les cas, vous devez ajouter plus de contrôles, par exemple. si ce n'est pas capable d'analyser le json.
Object.defineProperty(XMLHttpRequest.prototype,'responseJSON',{value:function(){
return (typeof this.response==='string'?JSON.parse(this.response):this.response);
},writable:false,enumerable:false});
Je pense que vous devez inclure jQuery pour utiliser responseJSON
.
Sans jQuery, vous pouvez essayer avec responseText et essayer comme eval("("+req.responseText+")");
[~ # ~] update [~ # ~] : Veuillez lire le commentaire concernant eval
, vous pouvez tester avec eval, mais don ne l'utilisez pas en extension de travail.
OR
use json_parse : il n'utilise pas eval
Utilisez nsIJSON s'il s'agit d'une extension 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;
}
Pour une page Web, utilisez simplement JSON.parse
au lieu de Components.classes["@mozilla.org/dom/json;1"].createInstance(Components.interfaces.nsIJSON.decode