Spec-Zone.ru › HTTP

Запросы диапазона

HTTP-запросы диапазона

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

Проверка поддержки частичных запросов сервером

Если HTTP-ответ содержит заголовок Accept-Ranges со значением, отличным от none, сервер поддерживает запросы диапазона. Если в ответах отсутствует заголовок Accept-Ranges, это означает, что сервер не поддерживает частичные запросы. Если запросы диапазона не поддерживаются, приложения могут адаптироваться к этому условию; например, менеджеры загрузок могут отключить кнопки приостановки, которые используют запросы диапазона для возобновления загрузки.

Чтобы проверить, поддерживает ли сервер запросы диапазона, можно отправить запрос HEAD и изучить заголовки, не запрашивая ресурс целиком. Если вы используете curl, можно указать флаг -I, чтобы отправить запрос HEAD:

curl -I https://i.imgur.com/z4d4kWk.jpg

В результате будет отправлен следующий HTTP-запрос:

HEAD /z4d4kWk.jpg HTTP/2
Host: i.imgur.com
User-Agent: curl/8.7.1
Accept: */*

Ответ содержит только заголовки и не включает тело ответа:

HTTP/2 200
content-type: image/jpeg
last-modified: Thu, 02 Feb 2017 11:15:53 GMT
…
accept-ranges: bytes
content-length: 146515

В этом ответе Accept-Ranges: bytes указывает, что в качестве единиц для определения диапазона можно использовать «bytes» (сейчас другие единицы использовать нельзя). Заголовок Content-Length также полезен: он указывает общий размер изображения, если вместо этого отправить такой же запрос с методом GET.

Запрос определённого диапазона у сервера

Если сервер поддерживает запросы диапазона, можно указать, какую часть или части документа сервер должен вернуть, добавив в HTTP-запрос заголовок Range.

Диапазоны из одной части

Для наглядности запросить один диапазон ресурса можно с помощью curl. Параметр -H добавляет строку заголовка к запросу; в данном случае это заголовок Range, запрашивающий первые 1024 байта. Последний параметр — --output - — позволяет вывести двоичные данные в терминал:

curl https://i.imgur.com/z4d4kWk.jpg -i -H "Range: bytes=0-1023" --output -

Отправленный запрос выглядит так:

GET /z4d4kWk.jpg HTTP/2
Host: i.imgur.com
User-Agent: curl/8.7.1
Accept: */*
Range: bytes=0-1023

Сервер отвечает статусом 206 Partial Content:

HTTP/2 206
content-type: image/jpeg
content-length: 1024
content-range: bytes 0-1023/146515
…

(binary content)

Заголовок Content-Length указывает размер запрошенного диапазона, а не полный размер изображения. Заголовок ответа Content-Range показывает, где это частичное сообщение находится в полном ресурсе.

Диапазоны из нескольких частей

Заголовок Range также позволяет получить сразу несколько диапазонов в документе, состоящем из нескольких частей. Диапазоны разделяются запятой.

curl http://www.example.com -i -H "Range: bytes=0-50, 100-150"

Сервер отвечает статусом 206 Partial Content, как показано ниже. Ответ содержит заголовок Content-Type, указывающий на то, что далее следует набор байтовых диапазонов из нескольких частей. Строка-разделитель (в данном случае 3d6b6a416f9b5) отделяет части тела сообщения, каждая из которых содержит собственные поля Content-Type и Content-Range:

HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5
Content-Length: 282

--3d6b6a416f9b5
Content-Type: text/html
Content-Range: bytes 0-50/1270

<!doctype html>
<html lang="en-US">
<head>
    <title>Example Do
--3d6b6a416f9b5
Content-Type: text/html
Content-Range: bytes 100-150/1270

eta http-equiv="Content-type" content="text/html; c
--3d6b6a416f9b5--

Условные запросы диапазона

При возобновлении загрузки и запросе дополнительных частей ресурса необходимо убедиться, что сохранённый ресурс не изменился с момента получения последнего фрагмента.

Заголовок HTTP-запроса If-Range делает запрос диапазона условным: если условие выполнено, отправляется запрос диапазона, а сервер возвращает ответ Partial Content со статусом 206 и соответствующим телом. Если условие не выполнено, сервер возвращает ресурс целиком со статусом OK 200. Этот заголовок можно использовать либо с валидатором Last-Modified, либо с ETag, но не с обоими одновременно.

If-Range: Wed, 21 Oct 2015 07:28:00 GMT

Ответы на частичные запросы

При работе с запросами диапазона важны три кода состояния:

  • На успешный запрос диапазона сервер отвечает статусом Partial Content 206.
  • Если запрошенный диапазон выходит за границы ресурса, сервер возвращает статус Requested Range Not Satisfiable 416. Это означает, что ни одно из значений диапазона не пересекается с размером ресурса. Например, начальная позиция байта каждого диапазона может быть больше длины ресурса.
  • Если запросы диапазона не поддерживаются, сервер возвращает статус OK 200 и передаёт всё тело ответа.

Сравнение с фрагментированной Transfer-Encoding

Заголовок Transfer-Encoding позволяет использовать фрагментированное кодирование, что удобно при отправке клиенту больших объёмов данных, когда общий размер ответа неизвестен до завершения обработки запроса. Сервер сразу отправляет данные клиенту, не буферизуя ответ и не определяя его точную длину, что снижает задержку. Запросы диапазона совместимы с фрагментированным кодированием и могут использоваться как вместе, так и по отдельности.

См. также

  • Связанные коды состояния: 200, 206, 416.
  • Связанные заголовки: Accept-Ranges, Range, Content-Range, If-Range, Transfer-Encoding.

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Range_requests

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API