Перечитать тело ответа из выборки JavaScript
fetch()
возвращает обещание, которое (в случае успеха) разрешается в Response
объект. Очень распространенная вещь, которую нужно сделать, это немедленно позвонить Response.json()
преобразовать тело ответа в объект JSON.
Если тело ответа не является допустимым JSON, то Response.json()
обещание не выполняется с ошибкой. Сообщение является чем-то вроде:
Неожиданный токен X в JSON в позиции 0
Это не очень полезно при диагностике проблемы; в идеале я хотел бы видеть контент с сервера (что часто является сообщением об ошибке).
Тем не менее, кажется, что вы можете только читать поток в Response.body
один раз (по крайней мере, в Chrome). (Там даже только для чтения Response.bodyUsed
флаг.) Это уже произошло, когда Response.json()
пытается преобразовать тело в JSON, поэтому тело оказывается потерянным навсегда в случае сбоя анализа JSON.
Есть ли способ восстановить исходное тело ответа... если не считать его вручную (а затем преобразовать в JSON), когда оригинал fetch
Обещание разрешается?
5 ответов
Использование Response.clone()
клонировать Response
let clone = response.clone();
В качестве альтернативы используйте Response.body.getReader()
который возвращает ReadableStream
читать Response
как поток, TextDecoder()
преобразовать Uint8Array
поток данных в текст.
Мне приходилось иметь дело с API, который иногда вызывал ошибку в ответе JSON - до возвращения response.json()
Я сделал клон объекта ответа. используя блок catch, я могу определить, является ли ошибка SyntaxError, и приступить к ее исправлению, используя текстовый результат клона ответа
немного так:
var brokenJson = function (url) {
var responseCopy;
return fetch(url)
.then(function (response) {
responseCopy = response.clone();
return response.json();
}).catch(function (err) {
if (err instanceof SyntaxError) {
return responseCopy.text()
.then(function(data) {
return fixJson(data);
});
}
else {
throw err;
}
}).then(function (json) {
// do things
});
};
fixJson
это просто функция, которая исправляет полученные данные - в моем случае, когда он был сломан JSON, он всегда был сломан одинаково - я думаю, что у него был дополнительный ведущий {или конечный} - не могу вспомнить
Перечитав вопрос, вы, скорее всего, захотите записать ошибку на консоль, а не исправлять json - легко переписать:
var brokenJson = function (url) {
var responseCopy;
return fetch(url)
.then(function (response) {
responseCopy = response.clone();
return response.json();
}).catch(function (err) {
if (err instanceof SyntaxError) {
return responseCopy.text()
.then(function(text) {
console.error(text);
throw err;
});
}
else {
throw err;
}
}).then(function (json) {
// do things
});
};
Назначение response.json() переменной и его возврат сработали для меня. clone() снова сказал, что он заблокирован.
fetch("http://localhost:3000/watchlist")
.then(response => {
var res = response.json();
return res;
})
.then(data => {
console.log(data);
this.setState({ data });
});
Как насчет?
fetch(url).then(async response => {
var response_text = await response.text();
var response_data = JSON.parse(response_text);
// do whatever you want now
// and if the JSON.parse() failed, you still have the original response_text
}
(На самом деле другие намекали на что-то вроде этого)
я использовал
JSON.parse(response.resp.data)
как-то клон не работал.