Разбор 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:
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();
Я думаю, что вы должны включить 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