Перенаправлять HTTP-запрос, только если предпочтителен определенный тип носителя

В HTTP, если клиент запрашивает ресурс при отправке определенных настроек типа мультимедиа (через проактивное согласование содержимого Accept заголовок), а представление этого ресурса недоступно в предпочтительном типе мультимедиа.

Теперь было бы приемлемо перенаправить клиента на другой URI (следовательно, семантически вероятный другой ресурс), который может обеспечить это представление?

В то же время, если клиент запросил бы тип мультимедиа, в котором имеется представление, доступное для ресурса, это представление затем будет доставлено.

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

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

Пример:

Ресурс семантически представляет список статей, и его представление доступно как общее text/html, Теперь клиент запрашивает его с предпочтением application/json-home, Сервер может знать, что этот тип медиа имеет смысл только для семантического домашнего ресурса, и перенаправить клиента к / путь к тому же сайту (где находится домашний ресурс). С другой стороны, если не будет предоставлен предпочтительный тип носителя или text/html представление запрашивается клиентом, это может быть ответом.

1 ответ

Решение

Короткий ответ на ваш вопрос: да, допустимо перенаправлять клиентов на другой URI на основе Accept заголовок, который отправляет клиент, и спецификация HTTP явно предусматривает этот сценарий.

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

406 (неприемлемо)

RFC 7231, кажется, предпочитает 406 (Not Acceptable) код состояния в этом сценарии. Из раздела 5.3.2:

If the [Accept] header field is
present in a request and none of the available representations for
the response have a media type that is listed as acceptable, the
origin server can either honor the header field by sending a 406 (Not
Acceptable) response or disregard the header field by treating the
response as if it is not subject to content negotiation.

Несмотря на то, что ответом является ошибка клиента 4xx, раздел 6.5.6 явно разрешает автоматический выбор других ресурсов и / или типов носителей, которые будут приемлемы для сервера:

The server SHOULD generate a payload containing a list of available
representation characteristics and corresponding resource identifiers
from which the user or user agent can choose the one most
appropriate.  A user agent MAY automatically select the most
appropriate choice from that list.  However, this specification does
not define any standard for such automatic selection, as described in
Section 6.4.1.

В вашем примере сценария полезная нагрузка вашего ответа может содержать ссылку на "домашний" ресурс и указывать, что его можно получить с помощью application/json-home тип носителя. (Он также может содержать ссылку на этот же ресурс, указывая, что он может быть получен с одним или несколькими другими типами мультимедиа.)

Хотя 406 не является редиректом (в смысле 3хх), спецификация явно позволяет клиенту автоматически переходить по ссылке (ссылкам) в вашем 406 ответе. Однако веб-браузер не будет делать это автоматически.

303 (см. Другие)

Вы также можете использовать 300 (Multiple Choices) или 303 (See Other)оба из которых явно указывают Location заголовок, который пользовательский агент может использовать для получения альтернативного URI. Если вам нужно автоматическое перенаправление, и ваш клиент является обычным веб-браузером (Chrome, Firefox и т. Д.), То наиболее практичным ответом, вероятно, будет возвращение сервером вашего 303 (See Other), Из RFC 7231, раздел 6.4.4:

The 303 (See Other) status code indicates that the server is
redirecting the user agent to a different resource, as indicated by a
URI in the Location header field, which is intended to provide an
indirect response to the original request.  A user agent can perform
a retrieval request targeting that URI (a GET or HEAD request if
using HTTP), which might also be redirected, and present the eventual
result as an answer to the original request.  Note that the new URI
in the Location header field is not considered equivalent to the
effective request URI.
[...]
A 303 response to a GET request indicates that the origin server does
not have a representation of the target resource that can be
transferred by the server over HTTP.  However, the Location field
value refers to a resource that is descriptive of the target
resource, such that making a retrieval request on that other resource
might result in a representation that is useful to recipients without
implying that it represents the original target resource.

С 303 сервер прямо говорит: "Этот URI, на который я перенаправляю вас, не эквивалентен URI, который вы хотели, но я думаю, что он может быть близок". Это похоже на то, что вы просили, и до тех пор, пока вы предоставляете предпочтительный URI в Location header, браузеры (и многие другие HTTP-клиенты) будут автоматически выполнять перенаправление.

300 (несколько вариантов)

300 (Multiple Choices) тоже вариант. Он предназначен для перенаправления пользователей на один из нескольких альтернативных URI для ресурса в рамках согласования реактивного содержимого (см. Раздел 3.4.2).

RFC 7231, раздел 6.4.1:

The 300 (Multiple Choices) status code indicates that the target
resource has more than one representation, each with its own more
specific identifier, and information about the alternatives is being
provided so that the user (or user agent) can select a preferred
representation by redirecting its request to one or more of those
identifiers.  In other words, the server desires that the user agent
engage in reactive negotiation to select the most appropriate
representation(s) for its needs (Section 3.4).

If the server has a preferred choice, the server SHOULD generate a
Location header field containing a preferred choice's URI reference.
The user agent MAY use the Location field value for automatic
redirection.

Хотя это не нарушает спецификацию выборочного возврата 300 на основе поддерживаемого клиентом медиа-типа, 406 будет более интуитивно понятным.

Vary: accept заголовок

Независимо от того, какой код статуса вы возвращаете, вы должны включить Vary: accept заголовок во ВСЕХ ответах для этого URI, включая 200 (или любой другой) ответ, отправленный, когда клиент делает запрос с приемлемым типом мультимедиа для этого ресурса. Vary заголовок явно предназначен для согласования согласованного содержимого, и он будет препятствовать тому, чтобы (совместимый) посредник или клиент обслуживали "неправильный" ответ на запрос с другим Accept заголовок. Смотрите раздел 7.1.4 для деталей.

Другие вопросы по тегам