您的问题的简短回答是肯定的,可以根据客户端发送的 Accept 标头将客户端重定向到不同的 URI,并且 HTTP 规范明确设想了这种情况。
如何以符合规范的方式执行此操作,包括您返回的状态代码,取决于您的资源的性质和您所服务的客户。这里有几个选项:
406(不可接受)
在这种情况下,RFC 7231 似乎更喜欢406 (Not Acceptable) 状态码。来自section 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 客户端错误,section 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.
在您的示例场景中,您的响应的有效负载可能包含指向“home”资源的链接,并指示可以使用 application/json-home 媒体类型检索它。 (它还可以包含指向同一资源的链接,表明可以使用一种或多种其他媒体类型来检索它。)
虽然 406 不是重定向(在 3xx 意义上),但规范明确允许客户端自动跟踪 406 响应中的链接。但是,Web 浏览器不会自动执行此操作。
303(见其他)
您还可以使用300 (Multiple Choices) 或303 (See Other),两者都明确指定用户代理可用于检索备用URI 的Location 标头。如果您确实需要自动重定向,并且您的客户端是一个普通的网络浏览器(Chrome、Firefox 等),那么最实际的响应可能是让您的服务器返回一个303 (See Other)。来自RFC 7231, section 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,但我认为它可能很接近。”这似乎非常接近您的要求,只要您在 Location 标头中提供首选 URI,浏览器(和许多其他 HTTP 客户端)将自动遵循重定向。
300(多选)
300 (Multiple Choices) 也是一个选项。它的设计更多是为了将用户重定向到资源的多个替代 URI 之一,作为反应式内容协商的一部分(请参阅section 3.4.2)。
RFC 7231, section 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标头
无论您返回什么状态代码,您都应该在此 URI 的所有响应中包含 Vary: accept 标头,包括客户端使用此资源的可接受媒体类型发出请求时发送的 200(或任何其他)响应. Vary 标头明确设计用于响应式内容协商,它将防止(兼容的)中介或客户端对具有不同 Accept 标头的请求提供“错误”响应。详情请见section 7.1.4。