Перехватчики¶
30.09.2026
HttpClient поддерживает разновидность промежуточного слоя — перехватчики.
Коротко: перехватчики выносят из отдельных запросов общие приёмы — повтор, кэш, журнал и аутентификацию.
У HttpClient два вида перехватчиков: функциональные и на инъекции зависимостей. Лучше функциональные: их поведение предсказуемее, особенно в сложной конфигурации. Примеры в этом руководстве — функциональные. Перехватчики на DI разобраны в конце.
Перехватчики¶
Перехватчик — это обычно функция, которая выполняется для каждого запроса и может менять содержимое и ход запроса и ответа. Несколько перехватчиков образуют цепочку: каждый обрабатывает запрос или ответ и передаёт его следующему.
На перехватчиках собирают типичные сценарии:
- Заголовок аутентификации у исходящих запросов к конкретному API.
- Повтор неудачных запросов с экспоненциальной задержкой.
- Кэш ответов на время или до сброса мутациями.
- Свой разбор ответов.
- Замер и запись времени ответа сервера.
- Элементы интерфейса вроде индикатора загрузки, пока идёт сеть.
- Сбор и пакетирование запросов за заданный промежуток времени.
- Автоматический срыв запроса по настраиваемому сроку или таймауту.
- Регулярный опрос сервера и обновление результатов.
Объявление перехватчика¶
Базовая форма — функция, которая получает исходящий HttpRequest и функцию next, следующий шаг цепочки.
Например, loggingInterceptor пишет URL исходящего запроса в console.log и передаёт запрос дальше:
1 2 3 4 5 6 7 | |
Чтобы перехватчик реально видел запросы, его нужно подключить к HttpClient.
Подключение перехватчиков¶
Набор перехватчиков задаётся при настройке HttpClient через инъекцию зависимостей, функцией withInterceptors:
1 2 3 | |
Перехватчики сцепляются в том порядке, в каком они перечислены в провайдерах. В примере выше loggingInterceptor обрабатывает запрос и передаёт его в cachingInterceptor.
События ответа¶
Перехватчик может преобразовать поток Observable из HttpEvent, который вернул next, чтобы прочитать или изменить ответ. В потоке все события ответа, поэтому итоговый объект ответа часто отличают по .type.
1 2 3 4 5 6 7 8 9 10 11 12 | |
Ответ естественно связан с исходящим запросом: перехватчик преобразует поток ответа в замыкании, которое захватило объект запроса.
Изменение запросов¶
Большинство свойств экземпляров HttpRequest и HttpResponse неизменяемы, и перехватчик не может поменять их на месте. Мутации делают через клон .clone(), указывая, какие свойства должны отличаться в новом экземпляре. Само значение при этом тоже обновляют неизменяемо (как HttpHeaders или HttpParams).
Например, чтобы добавить заголовок:
1 2 3 | |
Из-за неизменяемости большинство перехватчиков идемпотентны, если один и тот же HttpRequest проходит цепочку несколько раз. Так бывает, в частности, при повторе запроса после ошибки.
Тело запроса или ответа не защищено от глубокой мутации. Если перехватчику нужно менять тело, учитывайте, что он может выполниться на одном запросе несколько раз.
Инъекция зависимостей в перехватчиках¶
Перехватчики выполняются в контексте инъекции того инжектора, который их зарегистрировал, и могут получать зависимости через inject.
Допустим, в приложении есть сервис AuthService, который выдаёт токены для исходящих запросов. Перехватчик внедряет его и пользуется им:
1 2 3 4 5 6 7 8 9 10 | |
Метаданные запроса и ответа¶
Часто в запрос нужно вложить сведения, которые не уходят на сервер, а предназначены перехватчикам. У HttpRequest есть объект .context: он хранит такие метаданные как экземпляр HttpContext. Это типизированная карта с ключами типа HttpContextToken.
Ниже метаданные решают, включён ли перехватчик кэша для конкретного запроса.
Токены контекста¶
Чтобы в карте .context запроса хранить, должен ли перехватчик кэша сохранять этот запрос, заводят ключ HttpContextToken:
1 | |
Переданная функция создаёт значение токена по умолчанию для запросов, которые его явно не задали. Функция нужна, чтобы при значении-объекте или массиве у каждого запроса был свой экземпляр.
Чтение токена в перехватчике¶
Перехватчик читает токен и по значению решает, применять ли логику кэша:
1 2 3 4 5 6 7 8 9 | |
Токены контекста при запросе¶
В запросе через API HttpClient можно передать значения HttpContextToken:
1 2 3 | |
Перехватчики читают эти значения из HttpContext запроса.
Контекст запроса изменяем¶
В отличие от остальных свойств HttpRequest, связанный HttpContext изменяем. Если перехватчик меняет контекст запроса, который потом повторяют, тот же перехватчик увидит изменение при следующем запуске. Так между повторами передают состояние, если оно нужно.
Синтетические ответы¶
Большинство перехватчиков просто вызывает обработчик next, преобразуя запрос или ответ, но это не обязательное требование. Ниже — способы, которыми перехватчик добавляет более сложное поведение.
Вызывать next не обязательно. Ответ можно собрать иначе: из кэша или отправив запрос другим механизмом.
Ответ собирают конструктором HttpResponse:
1 2 3 | |
Сведения о перенаправлении¶
Когда HttpClient работает через серверную часть fetch, у ответа есть свойство redirected: ответ получен в результате перенаправления. Свойство совпадает со спецификацией Fetch API и пригождается в перехватчиках, которые обрабатывают редиректы.
Перехватчик читает сведения о перенаправлении и действует по ним:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
По тем же сведениям в перехватчике строят условную логику:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
Типы ответа¶
Когда HttpClient работает через серверную часть fetch, у ответа есть свойство type: как браузер обработал ответ с учётом политики CORS и режима запроса. Свойство совпадает со спецификацией Fetch API и помогает разбирать проблемы CORS и доступность ответа.
У свойства type ответа бывают такие значения:
'basic'— ответ того же источника, все заголовки доступны'cors'— кросс-доменный ответ с корректно настроенными заголовками CORS'opaque'— кросс-доменный ответ без CORS, заголовки и тело могут быть ограничены'opaqueredirect'— ответ перенаправленного запроса в режиме no-cors'error'— произошла сетевая ошибка
Перехватчик использует тип ответа, чтобы разбирать CORS и обрабатывать ошибки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
Перехватчики на DI¶
HttpClient также поддерживает перехватчики в виде внедряемых классов, которые настраиваются через DI. Возможности те же, что у функциональных перехватчиков, отличается механизм настройки.
Перехватчик на DI — внедряемый класс с интерфейсом HttpInterceptor:
1 2 3 4 5 6 7 | |
Такие перехватчики подключают мультипровайдером инъекции зависимостей:
1 2 3 4 5 6 7 8 9 10 | |
Перехватчики на DI выполняются в порядке регистрации провайдеров. В приложении с обширной иерархической конфигурацией DI этот порядок трудно предсказать.
Источник: https://angular.dev/guide/http/interceptors