为什么将 HEAD 请求转换为 GET 请求有用?

Why is it useful to convert HEAD requests to GET requests?

在新的 Phoenix 应用程序中,Plug.Head 插件默认存在,我对它的重要性很感兴趣。

我知道“the HEAD method is identical to GET except that the server MUST NOT send a message body in the response”。

我认为 official Phoenix guides are top-notch but this threw me off in the Routing guide:

Plug.Head - converts HEAD requests to GET requests and strips the response body

如果 HEAD 请求没有正文那么为什么需要这个?我想也许可以控制格式错误的请求,但看看 Plug.Head implementation,它只是将 HEAD 方法切换为 GET。

  def call(%Conn{method: "HEAD"} = conn, []), do: %{conn | method: "GET"}
  def call(conn, []), do: conn
end

关于这个主题,我能找到的最接近的东西是 question on ServerFault,但它与 NGINX 和有缺陷的应用程序逻辑有关,其中 HEAD 请求需要转换为 GET 并将相应的 GET 响应返回到头。

A​​FAICT,想法是 Plug.Head 只是确保请求被处理为 GET;实现 HEAD 的第二部分不是发送正文,它是由插头连接适配器完成的。大多数回调的文档,如 send_resp,指定 "If the request has method "HEAD", the adapter should not send the response to the client."

由于 Phoenix 很大程度上受到 Rails 的启发,您可以放心地打赌 Plug.Head is inspired by Rack::Head.

HEAD 请求 returns 与 GET 相同的响应,但仅 headers。因此,为了生成正确的 headers,它们会被路由到 Phoenix 应用程序中的 GET 操作。

但是要生成正确的(空的)body,必须去除响应的 body。因为 Rack::Head 是中间件,所以它会在收到控制器的响应后这样做。

相比之下,Plug的架构更像是一个管道,Plug.Head修改了方法并传递conn,但再也没有看到它。

如果您看到 cdegroot's answer,剥离响应的 body 的责任将传递给 Plug.Conn.Adapter 来执行(即网络服务器)。