По умолчанию Chrome и другие браузеры буферизируют весь ответ (заголовки и тело) XMLHttpRequest. Поэтому нет простого способа сначала проверить заголовки, а затем извлечь тело, используя XMLHttpRequest. Единственное решение - обрабатывать ответ как поток / чанки, а не как один ответ. В Firefox было "moz-chunked-arraybuffer"
для xhr.responseType
, но было удалено . Google Chrome реализован в какой-то момент xhr.responseType
"stream"
( как экспериментальный ), но он был отброшен в пользу whatwg Streams . На сегодняшний день самый простой fetch API
в большинстве современных браузеров дает нам возможность получать заголовки ответа без тела (если они уже отправлены сервером). Протестировано в Chrome 77:
let response = await fetch('http://localhost:9615/');
if (response.ok) {
console.log('status code:', response.status);
let text = await response.text();
console.log('text', text);
} else {
console.error('HTTP-Error:', response.status);
}
Вы также можете использовать прямо упомянутые потоки whatwg ( ReadableStream ), как здесь:
fetch("http://localhost:9615/").then((response) => {
const reader = response.body.getReader();
const stream = new ReadableStream({
start(controller) {
console.log('status code:', response.status);
function push() {
reader.read().then(({ done, value }) => {
console.log('read', value);
if (done) {
console.log('done');
controller.close();
return;
}
controller.enqueue(value);
push();
});
};
push();
}
});
return new Response(stream, { headers: { "Content-Type": "text/html" } });
});
В качестве тестового сервера я использовалкод ниже (NodeJS):
const http = require('http');
http.createServer(function (req, res) {
setTimeout(() => {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.flushHeaders();
setTimeout(() => {
res.write("some content");
res.end();
}, 3000);
}, 3000);
}).listen(9615);
В обоих решениях (Fetch API и ReadableStream) вы получите status code: 200
после первых 3000 мсек, а остальные ответы после следующих 3000 мс.
К сожалению, Потоки еще широко не поддерживаются браузерами, но здесь - это полифилл. Смотри также this .