Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

Документы

Медиа

Назад
Вопрос про Node.js: HTTP Range, partial content, 206 status code, Content-Range, file streaming, resumable download

Что такое Range-запросы и как они используются для частичной загрузки файлов?

Вопрос проверяет понимание HTTP Range-запросов и их применения для эффективной загрузки или скачивания больших файлов по частям.

Короткий ответ

Range-запросы — это HTTP-запросы, которые позволяют клиенту запросить только определённую часть файла, а не весь файл целиком. Клиент отправляет заголовок Range с указанием байтового диапазона, например, 'Range: bytes=0-999'. Сервер, поддерживающий эту функцию, отвечает статусом 206 (Partial Content) и отправляет запрошенный фрагмент с заголовком Content-Range. Это используется для докачки файлов после обрыва соединения, для потоковой передачи аудио/видео или для загрузки только нужной части большого файла, что экономит трафик и время.

Длинный ответ

Range-запросы — это стандартный механизм протокола HTTP, определённый в RFC 7233, который позволяет клиенту запрашивать у сервера не весь ресурс целиком, а только указанный диапазон байтов. Это фундаментальная технология для эффективной работы с большими файлами в сети.

Как это работает

Клиент, желающий получить часть файла, добавляет в свой GET-запрос заголовок Range. Значение этого заголовка указывает один или несколько байтовых диапазонов. Например:

  • Range: bytes=0-499 — запрашивает первые 500 байт файла.
  • Range: bytes=500-999 — запрашивает второй блок из 500 байт.
  • Range: bytes=-500 — запрашивает последние 500 байт файла.
  • Range: bytes=500- — запрашивает всё, начиная с 500-го байта и до конца файла.

Если сервер поддерживает Range-запросы, он отвечает статусом 206 Partial Content вместо обычного 200 OK. В ответе обязательно присутствует заголовок Content-Range, который указывает, какой именно диапазон был отправлен, и общий размер файла, например: Content-Range: bytes 0-499/12345. Тело ответа содержит только запрошенные байты.

Практическое применение

Эта технология используется в нескольких ключевых сценариях:

  • Возобновляемая загрузка (Resumable Download): Если загрузка большого файла прервалась, клиент (например, менеджер загрузок или браузер) может запросить оставшуюся часть файла, начиная с уже полученного байта, вместо того чтобы начинать сначала.
  • Потоковое мультимедиа (Streaming): Видео- и аудиоплееры используют Range-запросы для загрузки файла по частям (чанкам). Это позволяет реализовать перемотку: когда пользователь перемещает ползунок, плеер запрашивает данные с соответствующей позиции в файле.
  • Эффективная загрузка частей файлов: Приложение может загружать только заголовок файла (например, для проверки типа) или определённый сегмент данных из большого архива или образа диска.

Пример кода на стороне клиента (JavaScript)

// Пример использования Fetch API для загрузки первых 1024 байт файла
async function fetchFileRange(url, start, end) {
  const headers = new Headers();
  headers.append('Range', `bytes=${start}-${end}`);

  const response = await fetch(url, { headers });

  if (response.status === 206) {
    // Успешно получена часть файла
    const contentRange = response.headers.get('Content-Range');
    console.log(`Получен диапазон: ${contentRange}`);
    const blob = await response.blob();
    return blob;
  } else {
    // Сервер не поддерживает Range-запросы, вернул весь файл (статус 200)
    throw new Error('Сервер не поддерживает частичную загрузку');
  }
}

// Использование: загружаем первые 1024 байта
// fetchFileRange('https://example.com/large-video.mp4', 0, 1023);

Пример поддержки на стороне сервера (Node.js с Express)

const express = require('express');
const fs = require('fs').promises;
const path = require('path');

const app = express();

app.get('/download/:file', async (req, res) => {
  const filePath = path.join(__dirname, 'uploads', req.params.file);
  try {
    const stat = await fs.stat(filePath);
    const fileSize = stat.size;

    // Получаем заголовок Range от клиента
    const range = req.headers.range;

    if (range) {
      // Парсим диапазон, например "bytes=0-999"
      const parts = range.replace(/bytes=/, "").split("-");
      const start = parseInt(parts[0], 10);
      const end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1;

      const chunkSize = (end - start) + 1;
      const file = await fs.open(filePath, 'r');
      const buffer = Buffer.alloc(chunkSize);
      await file.read(buffer, 0, chunkSize, start);
      await file.close();

      // Отправляем частичный контент
      res.writeHead(206, {
        'Content-Range': `bytes ${start}-${end}/${fileSize}`,
        'Accept-Ranges': 'bytes',
        'Content-Length': chunkSize,
        'Content-Type': 'application/octet-stream'
      });
      res.end(buffer);
    } else {
      // Если заголовка Range нет, отправляем весь файл
      res.writeHead(200, {
        'Content-Length': fileSize,
        'Content-Type': 'application/octet-stream'
      });
      const fileStream = fs.createReadStream(filePath);
      fileStream.pipe(res);
    }
  } catch (err) {
    res.sendStatus(404);
  }
});

app.listen(3000);

Вывод: Range-запросы следует применять везде, где возможна работа с большими файлами — в системах загрузки файлов, стриминговых сервисах, облачных хранилищах. Они значительно улучшают пользовательский опыт, позволяя возобновлять прерванные загрузки и эффективно передавать медиаконтент, экономя трафик и серверные ресурсы.

Уровень

  • Рейтинг:

    3

  • Сложность:

    5

Навыки

  • Node.js

    Node.js

  • Networks

Ключевые слова

#HTTP Range

#partial content

#206 status code

#Content-Range

#file streaming

#resumable download

Подпишись на React Developer в телеграм