Можно ли получить данные объекта response до преобразования в json в JavaScript
Что проверяют
Понимаете ли вы, что Response это обёртка над потоком, а не готовый объект с данными. Отсюда все следствия: что доступно сразу, почему методы чтения асинхронные и почему тело читается один раз.
Как отвечать
Да, часть данных доступна ещё до чтения тела. Промис от fetch разрешается, как только пришли заголовки, поэтому status, ok, redirected, url, type и headers можно читать сразу, тело в этот момент ещё едет.
Само тело достают методами text(), json(), arrayBuffer(), blob(), formData(). Все они асинхронные, потому что дочитывают поток до конца. Никакой магии в json() нет, это тот же текст плюс разбор.
Главное ограничение: тело читается ровно один раз. После первого вызова свойство bodyUsed становится истиной, а повторный вызов бросает исключение. Если нужны и сырой текст, и разобранный объект, читают текст один раз:
const res = await fetch(url);
if (!res.ok) throw new Error(String(res.status));
const raw = await res.text();
const data = JSON.parse(raw);Когда тело нужно двум независимым потребителям, делают res.clone() до первого чтения. А для прогресса загрузки поток читают вручную через res.body.getReader().
Где спотыкаются
В обработчике ошибки пробуют прочитать тело второй раз, чтобы залогировать ответ сервера. Вместо настоящей причины в лог уходит жалоба на уже прочитанный поток, и отладка сворачивает совсем не туда.
Второе: ждут, что fetch сам упадёт на коде ответа. Промис отклоняется только на сетевой ошибке или прерывании, а 404 и 500 для него совершенно нормальный ответ. Проверять ok приходится руками.
Третье: зовут clone() после того, как тело уже начали читать, или клонируют и читают только одну копию. В первом случае исключение, во втором данные копятся в памяти, потому что клон вынуждает браузер буферизовать поток целиком.