Разбор 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 ответов:
новые способы I:
fetchTL; 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();
Я думаю, что вы должны включить jQuery, чтобы использовать
responseJSON.без jQuery, вы можете попробовать с responseText и попробовать как
eval("("+req.responseText+")");обновление:пожалуйста, прочитайте комментарий в отношении
eval, вы можете проверить с eval, но не используйте его в рабочем расширении.или
использовать json_parse : не используйте
eval
примечание: Я только проверил это в Chrome.
он добавляет функцию прототипа в XMLHttpRequest .. XHR2,
на XHR 1 вам, вероятно, просто нужно заменить
this.responseСthis.responseTextObject.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