为什么将HEAD请求转换为GET请求很有用?
在新的凤凰应用程序中,Plug.Head
插件默认存在,我对它的重要性很感兴趣。为什么将HEAD请求转换为GET请求很有用?
我觉得official Phoenix guides是一流的,但是这把我关在Routing guide:
Plug.Head - 转换HEAD请求GET请求,并除去 响应主体
如果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请求回到HEAD一个有缺陷的应用程序逻辑。
AFAICT,这个想法是,Plug.Head
只是确保该请求被处理为GET
;实施HEAD
的第二部分不是发送正文,由插头连接适配器完成。大多数回调的文档(如send_resp)指定“如果请求具有方法"HEAD"
,则适配器不应将响应发送给客户端。”
由于凤凰在很大程度上是由Rails的启发,你可以放心地赌Plug.Head
由Rack::Head
.
HEAD请求返回如GET,但只有标题相同的反应启发。所以为了生成正确的标题,他们被路由到您的凤凰应用中的GET操作。
但是为了产生正确的(空的)正文,必须将正文的正文删除。因为Rack::Head
是中间件,所以它在得到控制器的响应后就会这样做。
相比之下,Plug的架构更像流水线,Plug.Head
修改方法并传递conn
,但从未再次看到它。
如果您看到cdegroot's answer,那么该责任被传递给Plug.Conn.Adapter
以实现(即网络服务器)。
所以简单的答案是** HEAD - > GET转换是为了使路由匹配更容易?**我用'curl' HEAD和GET请求测试了一个简单的Phoenix应用程序,响应正确,日志显示HEAD请求正确的(虽然'Plug.Logger'在'Plug.Head'之前这并不奇怪)。所以我猜想最初的请求方法保留在某个地方,但这对于另一个问题是重要的。 –
感谢您指出连接适配器!尽管引用的评论或者是不准确的,或者我仍然远离大局,因为我从“适配器不应该将响应**主体**发送给客户端”错过“** body **”一词。响应独立于请求方法发送,只有主体从对HEAD的响应中被省略。但是,我可能会误解适配器是如何工作的。 –
评论是正确的。服务器不应在**响应**中向HEAD **请求**发送主体。 HEAD **请求**本身是否具有主体是无关紧要的。 –