HTTPQUERY
Русский

412 Precondition Failed

Применение

Получив сообщение об ошибке 412 Precondition Failed, клиент понимает, что одно или несколько условий, указанных в запросе, не выполнены и ресурс не находился в ожидаемом состоянии. Конкретное поведение зависит от заголовка предусловия. Невыполнение If-Match возвращает 412 для любого метода. Невыполнение If-None-Match возвращает 304 для GET и HEAD и 412 для всех остальных методов.

Это похоже на 304, однако в случае 304 ресурс не был отправлен потому, что у клиента уже имелась самая свежая версия, и повторная передача не нужна.

Влияние на SEO

Поисковые системы, такие как Google, не будут индексировать URL со статусом ответа 412. Ранее проиндексированные URL будут удалены из результатов поиска.

Пример

Клиент хочет ответить на запись в блоге, но только при условии, что запись не изменялась с момента последнего просмотра ресурса клиентом. Условие передаётся в заголовке If-Unmodified-Since. Когда условие не выполняется, значит ресурс был изменён, и сервер отвечает 412 Precondition Failed, показывая, что запрос не выполнен.

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

Запрос

POST /blog/update?postid=111&task=reply HTTP/1.1
Host: example.com
If-Unmodified-Since: Fri, 1 Jan 2021 00:00:00 GMT
Content-Type: text/plain
Content-Length: 45

<Message body contains reply-text from the client>

Ответ

HTTP/1.1 412 Precondition Failed
Content-Type: text/html
Content-Length: 139

<html>
  <head>
    <title>Blog Update Error</title>
  </head>
  <body>
   <p>The post has changed since last viewed.</p>
  </body>
</html>

Как исправить

Получите текущую версию ресурса запросом GET или HEAD, чтобы узнать актуальное значение ETag или Last-Modified. Замените устаревший валидатор в заголовке If-Match или If-Unmodified-Since на текущий и повторите запрос.

При использовании оптимистичного управления параллелизмом (распространено в REST API и CMS-платформах) порядок действий таков:

Очистка кэша браузера устраняет ошибки 412, вызванные устаревшими закэшированными валидаторами. Браузер хранит устаревший ETag или временную метку и автоматически прикрепляет старые условные заголовки к запросам.

Кэширующие прокси и CDN между клиентом и сервером-источником иногда отдают устаревшие валидаторы. Убедитесь, что конфигурации прокси пропускают условные заголовки без изменений. Например, AWS CloudFront возвращает 412, когда заголовок If-Match в запросе GET не совпадает с ETag объекта. В таких случаях убедитесь, что кэш CDN свежий, либо выполните инвалидацию дистрибуции.

412 и 409

И 412, и 409 указывают на конфликт состояния, но причина различается. Ответ 412 означает, что заголовок предусловия (If-Match или If-Unmodified-Since) был вычислен как ложный. Ответ 409 означает, что запрос конфликтует с текущим состоянием ресурса независимо от условных заголовков. Используйте 412 для проверок оптимистичного параллелизма на основе ETag или временных меток. Используйте 409 для конфликтов бизнес-логики, таких как дублирующиеся записи или недопустимые переходы состояний.

Примеры кода

.NET

HttpStatusCode.PreconditionFailed

Rust

http::StatusCode::PRECONDITION_FAILED

Rails

:precondition_failed

Go

http.StatusPreconditionFailed

Symfony

Response::HTTP_PRECONDITION_FAILED

Python3.5+

http.HTTPStatus.PRECONDITION_FAILED

Java

java.net.HttpURLConnection.HTTP_PRECON_FAILED

Apache HttpComponents Core

org.apache.hc.core5.http.HttpStatus.SC_PRECONDITION_FAILED

Angular

@angular/common/http/HttpStatusCode.PreconditionFailed