Задать вопрос
@223606322
начинающий web-разработчик

Как сделать прогрессбар с процентами для получения ответа c json по api?

вот код https://codepen.io/Ron3485/pen/rNJRRwM

Здесь делается запрос на сервер и после чего полученный JSON файл с данными выводится в разметку.
Как сделать чтобы можно было видеть значение в процентах через сколько завершиться загрузка JSON.
Типа отправил запрос это 0% пока запрос идет значение увеличивается, а после того как пришел ответ, то значение становиться 100%, означающее, что весь JSONзагрузился
  • Вопрос задан
  • 462 просмотра
Подписаться 2 Средний Комментировать
Решения вопроса 2
@Ne7Le4Der
C помощью axios это довольно просто делается

https://codesandbox.io/s/axios-ondownloadprogress-...
Ответ написан
@GrayHorse
Можно использовать TransformStream.
Кода будет поменьше, чем если создавать "прокси" ReadableStream. Единственное отличие, что TransformStream "ленивый". Т.е. если закомментировать await newResponse.blob(); onProgress не будет вызываться, хотя данные были загружены.

Собственно вот онлайн демо.

const response = await fetch("https://fetch-progress.anthum.com/30kbps/images/sunrise-baseline.jpg");
total.value    = parseInt(response.headers.get("content-length")) || 0;

function onProgress(chunk) {
    loaded.value += chunk.length;
}
const ts = new TransformStream({
    transform(chunk, controller) {
        onProgress(chunk);
        controller.enqueue(chunk);
    },
});
response.body.pipeThrough(ts);
const newResponse = new Response(ts.readable);

const blob = await newResponse.blob();


Имей в виду, что "content-length" может отсутствовать.

А также данные могут быть сжаты, если есть заголовок "content-encoding", который, к слову, по-умолчанию будет недоступен для кода при кросс-доменных запросах.

И при "content-encoding" в "content-length" значение всегда указано для сжатого респонса, а в коллбеке будут уже не сжатые данные. Т.е. loaded в таком случае будет больше значения total ("content-length")

---

"Прокси" ReadableStream:
const reader = response.body.getReader();
const readableStream = new ReadableStream({
    async start(controller) {
        while (true) {
            const {done, value} = await reader.read();
            if (done) { break; }
            onProgress(value);
            controller.enqueue(value);
        }
        controller.close();
        reader.releaseLock();
    },
    cancel() {
        void reader.cancel();
    }
});
const newResponse = new Response(readableStream);
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы