Fetch | Заголовки

Fetch | Заголовки

Версия документа от 08 ноября 2021 года. Может измениться в будущем.

 

Список заголовков (Header list) — это список из нуля или более заголовков. Это изначально пустой список.

Примечание

Список заголовков по сути является специализированной мультикартой. Упорядоченный список пар ключ-значение с потенциально дублирующимися ключами.

Чтобы получить значение структурированного поля (get a structured field value) с указанием имени заголовка name и и строки type из списка заголовков list, выполните следующие действия:

1. Утверждено: type является одним из "dictionary" (словарь), "list" (список) или "item" (элемент).
2. Пусть value будет результатом получения name из list.
3. Если value равно «null», вернуть «null».
4. Пусть result будет результатом синтаксического анализа структурированных полей с «input_string», установленным в value, и «header_type», установленным в type.
5. Если синтаксический анализ не удался, верните «null».
6. Верните result.
Примечание

«Получение значения структурированного поля» намеренно не делает различий между отсутствующим «заголовком» и его «значением«, которое не может быть проанализировано как «значение структурированного поля«. Это обеспечивает равномерную обработку всей веб-платформы.

 

Чтобы установить значение структурированного поля (set a structured field value) для кортежа (имя заголовка name, значение структурированного поля structuredValue) в списке заголовков list, выполните следующие действия:

1. Пусть serializedValue будет результатом выполнения алгоритма сериализации структурированных полей в structuredValue.
2. Набор(name, serializedValue) в list.
Примечание

Значения структурированных полей определяются как объекты, которые HTTP может (в конечном итоге) сериализовать интересными и эффективными способами. На данный момент Fetch поддерживает значения заголовков только в виде байтовых последовательностей, что означает, что эти объекты могут быть установлены в списках заголовков только посредством сериализации, а их можно получить из списков заголовков только путем синтаксического анализа. В будущем то, что они являются объектами, может быть сохранено от начала до конца. [RFC8941]

 

Список заголовков list содержит (contains) имя заголовка name, если list содержит заголовок, имя которого нечувствительно к регистру байтов для name.

Чтобы получить (get) имя заголовка name из списка заголовков list, выполните следующие действия:

1. Если list не содержит name, верните null.
2. Верните значения всех заголовков в list, чье имя является нечувствительным к регистру байтов совпадающим с name, отделенных друг от друга 0x2C 0x20, по порядку.

Чтобы получить, декодировать и разделить (get, decode, and split) имя заголовка name из списка заголовков list, выполните следующие действия:

1. Пусть initialValue будет результатом получения name из list.
2. Если initialValue равно null, вернуть null.
3. Пусть input будет результатом изоморфного декодирования initialValue.
4. Пусть position будет позиционной переменной для input, изначально указывая на начало input.
5. Пусть values будет списком из строк, изначально пустой.
6. Пусть value будет пустой строкой.
7. Пока position не заканчивается после input:
   7.1. Добавьте результат сбора последовательности кодовых точек, которые не являются U+0022 (") или U+002C (,) из input, заданного position, в value.
      Примечание! Результатом может быть пустая строка.
   7.2. Если position не заканчивается после input, то:
      7.2.1. Если кодовая точка в position внутри input равна U+0022 ("), то:
         7.2.1.1. Добавить результат сбора строки в кавычках HTTP из input, заданной position, в value.
         7.2.1.2. Если position не заканчивается после input, то продолжайте.
      7.2.2. В противном случае:
         7.2.2.1. Утверждено: кодовая точка в position внутри input равна U+002C (,).
         7.2.2.2. Продвиньте position на 1.
   7.3. Удалите все табуляции и пробелы HTTP от начала и конца value.
   7.4. Добавьте value к values.
   7.5. Установите value в пустую строку.
8. Верните values

 

Пример

Вот как на практике получают, декодируют и разделяют функции с `A` в качестве аргумента name:

Заголовки (как в сети) Вывод
A: nosniff, « «nosniff», «» »
A: nosniff
B: sniff
A:
A: text/html;», x/x « «text/html;», x/x» »
A: text/html;»
A: x/x
A: x/x;test=»hi»,y/y « «x/x;test=»hi»», «y/y» »
A: x/x;test=»hi»
C: **bingo**
A: y/y
A: x / x,,,1 « «x / x», «», «», «1» »
A: x / x
A: ,
A: 1
A: «1,2», 3 « «»1,2″», «3» »
A: «1,2»
D: 4
A: 3

 

Чтобы добавить (append) заголовок (name, value) в список заголовков list, выполните следующие действия:

1. Если list содержит name, тогда установите name равным имени первого такого заголовка.
Примечание!

Это повторно использует регистр имени заголовка, уже имеющегося в списке list, если таковой имеется. Если есть несколько совпадающих заголовков, их имена будут одинаковыми.

2. Добавьте(name, value) в list.

 

Чтобы удалить (delete) имя заголовка name из списка заголовков list, удалите все заголовки, имя которых НЕ зависит от регистра символов и соответствует name из list.

 

Чтобы установить (set) заголовок (name, value) в списке заголовков list, выполните следующие действия:

1. Если list содержит name, тогда установите значение первого такого заголовка равным value и удалите остальные.
2. В противном случае, добавьте новый заголовок с именем name и значением value в list.

 

Чтобы объединить (combine) пару имя/значение «name/value» в список заголовков «list», выполните следующие действия:

1. Если list содержит name, тогда установите значение первого такого заголовка равным его значению, затем 0x2C, 0x20, а затем «value».
2. В противном случае добавьте новый заголовок с именем name и значением value в list.
Примечание

Объединение (Combine) использует XMLHttpRequest и протоколом рукопожатия WebSocket.

 

Чтобы преобразовать имена заголовков в упорядоченный набор строчных букв (convert header names to a sorted-lowercase set) с учетом списка имен headerNames, выполните следующие действия:

1. Пусть headerNamesSet будет новым упорядоченным набором.
2. Для каждого name из headerNames добавьте результат байтового name в headerNamesSet.
3. Верните результат сортировки headerNamesSet в порядке возрастания с байтом меньше.

 

Чтобы отсортировать и объединить (sort and combine) список заголовков list, выполните следующие действия:

1. Пусть headers будут пустым списком из заголовков (пар имя-значение), ключом является имя и значением является value.
2. Пусть names будет результатом преобразования имен заголовков в набор из отсортированных строчных букв со всеми именами заголовков в list.
3. Для каждого name в names:
   3.1. Пусть value будет результатом получения name из list.
   3.2. Утверждено: value не является null.
   3.3. Добавьте (name, value) к headers.
4. Верните headers

 

Заголовок (header) — это кортеж, состоящий из имени (nameимени заголовка) и значения (valueзначения заголовка). Заголовок состоит из имени и значения.

Имя заголовка (header name) — это последовательность байтов, которая соответствует производству токена имени поля.

Значение заголовка (header value) — это последовательность байтов, которая соответствует следующим условиям:

Примечание

Определение значения заголовка не определяется с точки зрения производства токена HTTP, поскольку оно повреждено.

Чтобы нормализовать (normalize) «potentialValue«, удалите все начальные и конечные байтовые пробелы HTTP из «potentialValue«.

Чтобы нормализовать (normalize) последовательность байтов potentialValue, удалите все начальные и конечные байты HTTP-пробелов  из potentialValue.

 

Чтобы определить, является ли заголовок (name, value) заголовком запроса CORS-safelisted (CORS-safelisted request-header), выполните следующие действия:

1. Если длина value больше 128, вернуть false.
2. Байт-нижний регистр name в нижнем регистре и включите результат:
   `accept`
      Если value содержит байт заголовка запроса небезопасного CORS, то возвращает false.
   `accept-language`
   `content-language`
      Если value содержит байт, который не находится в диапазоне от 0x30 (0) до 0x39 (9), включительно, не находится в диапазоне от 0x41 (A) в 0x5A (Z), включительно, не находится в диапазоне 0x61 (a) в 0x7A (z) включительно, и не 0х20 (SP), 0x2A (*), 0x2C (,), 0x2D (-), 0x2E (.), 0x3B (;) или 0x3D (=), а затем возвращает false.
   `content-type`
      Если value содержит небезопасный CORS-байт заголовка запроса, вернуть false.
      Пусть mimeType будет результатом синтаксического анализа value.
      Если mimeType является ошибкой, вернуть false.
      Если сущность mimeType не является "application/x-www-form-urlencoded", "multipart/form-data" или "text/plain", верните false.

ВНИМАНИЕ!

Это преднамеренно не использует извлечение MIME-типа, поскольку этот алгоритм довольно простителен, и серверы не должны его реализовывать.

Пример

Если используется извлечение типа MIME, следующий запрос не приведет к предварительному просмотру CORS, и наивный анализатор на сервере может обработать тело запроса как JSON:

fetch("https://victim.example/naïve-endpoint", {
   method: "POST",
   headers: [
      ["Content-Type", "application/json"],
      ["Content-Type", "text/plain"]
   ],
   credentials: "include",
   body: JSON.stringify(exerciseForTheReader)
});
   `range`
      Если value не является значением заголовка простого диапазона, возвращается false.
   В противном случае
      Вернуть false.
3. Вернуть true
Примечание

Существуют ограниченные исключения для списка безопасности заголовка `Content-Type`, как описано в исключениях протокола CORS.

Байт заголовка запроса в небезопасном CORS (CORS-unsafe request-header byte) — это байт byte, для которого выполняется одно из следующих условий:

  • «byte» меньше 0x20 и не равен 0x09 HT
  • «byte» — это 0x22 («), 0x28 (left parenthesis), 0x29 (right parenthesis), 0x3A (:), 0x3C (<), 0x3E (>), 0x3F (?), 0x40 (@), 0x5B ([), 0x5C (\), 0x5D (]), 0x7B ({), 0x7D (}), или 0x7F DEL.

 

Имена заголовка запроса в небезопасном CORS (CORS-unsafe request-header names), учитывает список заголовков headers, определяются следующим образом:

1. Пусть unsafeNames будет новым списком.
2. Пусть potentiallyUnsafeNames будут новым списком.
3. Пусть safelistValueSize будет 0.
4. Для каждого header из headers:
   4.1. Если header не является заголовком запроса, сохраненным в CORS, добавьте имя header в unsafeNames.
   4.2. В противном случае добавьте имя header в potentiallyUnsafeNames и увеличьте safelistValueSize на длину значения header.
5. Если safelistValueSize больше 1024, то для каждого name из potentiallyUnsafeNames добавьте имя name к unsafeNames.
6. Возврат результата преобразования имен заголовков в отсортированный строчный набор с unsafeNames.

 

Имя заголовка запроса без подстановочных знаков CORS (CORS non-wildcard request-header name) — это имя заголовка, которое не зависит от регистра байта и соответствует `Authorization`.

Привилегированное имя заголовка запроса без CORS (privileged no-CORS request-header name) — это имя заголовка, которое является совпадением без учета регистра байтов для одного из

  • `Range`
Примечание

Это заголовки, которые могут быть установлены привилегированными API и будут сохранены, если их связанный объект запроса будет скопирован, но будут удалены, если запрос будет изменен непривилегированными API.

Заголовки `Range` обычно используются загрузками и медиа-выборками, хотя ни один из них в настоящее время не определяет, как. HTML/2914 стремится решить эту проблему.

Предусмотрен помощник для добавления заголовка диапазона к конкретному запросу.

 

Имя заголовка ответа, содержащееся в списке безопасности CORS (CORS-safelisted response-header name), с учетом списка имен заголовков list, является именем заголовка, которое является совпадением без учета регистра байтов для одного из

 

Имя заголовка запроса без CORS-безопасного списка (no-CORS-safelisted request-header name) — это имя заголовка, которое не зависит от регистра байтов для одного из

  • `Accept`
  • `Accept-Language`
  • `Content-Language`
  • `Content-Type`

 

Чтобы определить, является ли заголовок header заголовком запроса без CORS-безопасного списка (no-CORS-safelisted request-header), выполните следующие действия:

1. Если имя header не является именем заголовка запроса без внесенного в CORS списка, верните false.
2. Вернуть, является ли header заголовком запроса в безопасном списке CORS.

 

Запрещенное имя заголовка (forbidden header name) — это имя заголовка, которое не учитывает регистр байтов для одного из

или имя заголовка, которое начинается с нечувствительного к регистру байта совпадения для `proxy-` или `sec-` (включая нечувствительное к регистру байта совпадение только для `Proxy-` или `Sec-`).

Примечание

Они запрещены, поэтому пользовательский агент остается под полным контролем над ними. Имена заголовков, начинающиеся с `Sec-`, зарезервированы для того, чтобы позволять создавать новые заголовки, защищенные от API, использующих fetch, которые позволяют контролировать заголовки разработчикам, таким как XMLHttpRequest. [XHR]

 

Запрещенное имя заголовка ответа (forbidden response-header name) — это имя заголовка, которое без учета регистра байтов соответствует одному из:

  • `Set-Cookie`
  • `Set-Cookie2`

 

Имя заголовка тела запроса (request-body-header name) — это имя заголовка, которое без учета регистра байтов соответствует одному из:

  • `Content-Encoding`
  • `Content-Language`
  • `Content-Location`
  • `Content-Type`

 

Чтобы извлечь значения заголовков (extract header values) с учетом заголовка header, выполните следующие действия:

1. Если при синтаксическом анализе значения header, согласно ABNF для имени header, происходит сбой, возвращается ошибка.
2. Вернуть одно или несколько значений, полученных в результате анализа значения header, в соответствии с ABNF для имени header.

 

Чтобы извлечь значения списка заголовков (extract header list values) с учетом имени заголовка name и списка заголовков list, выполните следующие действия:

1. Если list не содержит name, вернуть null.
2. Если ABNF для name допускает один заголовок, а list содержит более одного, возвращает ошибку.
Примечание

Если требуется другая обработка ошибок, сначала извлеките нужный заголовок.

3. Пусть values будет пустым списком.
4. Для каждого заголовка header список list содержит чье имя name:
   4.1. Пусть extract будет результатом извлечения значений заголовка из header.
   4.2. Если extract является ошибкой, вернуть ошибку.
   4.3. Добавляйте каждое значение в extract по порядку к values.
5. Верните values

 

Чтобы определить, является ли байтовая последовательность value значением простого заголовка диапазона (simple range header value), выполните следующие действия. Они возвращают логическое значение.

1. Пусть данные data будут изоморфным декодированием значения value.
2. Если данные data не начинаются с "bytes=", вернуть false.
3. Пусть позиция position будет переменной позицией для данных data, изначально указывающей на 6-ю кодовую точку data.
4. Пусть rangeStart будет результатом сбора последовательности кодовых точек, которые являются цифрами ASCII, из data, заданных в position.
5. Если кодовая точка в position в data не является U+002D (-), вернуть false.
6. Продвинуть позицию position на 1.
7. Пусть rangeEnd будет результатом сбора последовательности кодовых точек, которые являются цифрами ASCII, из данных data, заданных в позиции position.
8. Если позиция position не превышает конец данных data, вернуть false.
9. Если длина rangeEnd равна 0, вернуть true.
Примечание

Конец диапазона можно не указывать, например, «bytes = 0-» допустимо.

10. Если rangeStart, интерпретируемый как десятичное число, больше, чем rangeEnd, интерпретируемый как десятичное число, возвращается false.
11. Верните true.
Примечание

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

 

Значение `User-Agent` по умолчанию — это определяемое реализацией значение заголовка для заголовка `User-Agent`.

 

Информационные ссылки

Стандарт Fetchhttps://fetch.spec.whatwg.org/#terminology-headers

Перевод стандарта Fetch — https://efim360.ru/fetch/