使用HEAD请求时的Content-Length头字段?

72

HTTP规范 中关于 HEAD 请求的说明如下:

HEAD 方法与 GET 方法相同,除了服务器在响应中不得返回消息正文。响应 HEAD 请求时 HTTP 头中包含的元信息应该与响应 GET 请求时发送的信息相同.

HEAD 请求的响应是否应包含 Content-Length 头?它是否应该是在没有响应正文的情况下 GET 请求将返回的值?还是应该为 0?

6个回答

58

在我看来,HTTP 1.1 RFC非常明确:

Content-Length实体头字段表示发送给接收方的实体正文的大小,以十进制字节数表示。 对于HEAD方法,则表示如果请求是GET,则会发送哪些实体正文的大小。


5
有趣的是,curl 告诉你缺少主体...他们可能在读取回复时不知道这个方法是 HEAD,并认为主体丢失。 - Alexis Wilke
15
curl --head 的表现比 curl -X HEAD 更好。 - Beni Cherniavsky-Paskin
我们不理解它的意思,你能简单地说一下吗? - Hassan Faghihi
1
HEAD请求中,@deadManN要求Content-Length应该与GET请求中的长度相同,即使实际上没有正文。 - nietaki
5
由于RFC 2616已被RFC 7230-7237取代,因此不再相关。 RFC 7231的第4.3.2节指出:“服务器应该在响应HEAD请求时发送与如果请求是GET相同的标头字段,但可以省略有效载荷标头字段(第3.3节)。” 第3.3节中定义的有效载荷标头字段包括Content-LengthContent-RangeTrailerTransfer-Encoding - Piotr Dobrogost

45

HTTP/1.1规范第14.13节详细说明了Content-Length头字段,并指出:

  

应用程序应该使用此字段来指示消息正文的传输长度,除非根据第4.4节的规则禁止这样做。

在RFC中,“SHOULD”这个词有非常特定的含义

  
      
  1. SHOULD 这个词或形容词“建议性的(RECOMMENDED)”表示在特定情况下存在有效理由忽略某一项,但在选择不同课程之前必须充分了解和仔细权衡全部影响。
  2.   

因此,您可能并不总是看到Content-Length。通常,对于任何动态生成的内容,您可能不会看到它,因为为探索性HEAD请求提供服务可能过于昂贵。例如,对于静态文件,请针对Apache发出的HEAD请求将具有Content-Length,但是对于PHP脚本的请求可能没有。

例如,请尝试此网站...

telnet stackoverflow.com 80

HEAD / HTTP/1.0
Host:stackoverflow.com

HTTP/1.1 200 OK
Date: Mon, 11 Jan 2016 10:58:25 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Set-Cookie: __cfduid=c2eb4742a1e02d89cab0402220736c0bd1452509905; expires=Tue, 10-Jan-17 10:58:25 GMT; path=/; domain=.stackoverflow.com; HttpOnly
Cache-Control: public, no-cache="Set-Cookie", max-age=36
Expires: Mon, 11 Jan 2016 10:59:02 GMT
Last-Modified: Mon, 11 Jan 2016 10:58:02 GMT
Vary: *
X-Frame-Options: SAMEORIGIN
X-Request-Guid: 487e80bc-3783-4cfd-d883-a3bc84253234
Set-Cookie: prov=8dc24306-c067-45eb-bf5d-cffa855c2b03; domain=.stackoverflow.com; expires=Fri, 01-Jan-2055 00:00:00 GMT; path=/; HttpOnly
Server: cloudflare-nginx
CF-RAY: 26303c15f8e035a2-LHR

没有内容长度。


7
值得注意的是,如果响应是 Transfer-Encoding: chunked 的话,你也看不到 Content-Length - Rob
@PaulDixon,您能为这个帖子提供一些见解吗?谢谢。https://dev59.com/RVsX5IYBdhLWcg3wDb6L - smwikipedia
现在(2016年1月11日),对google.com的HEAD请求也会返回Content-Length - zpon
啊,那个例子已经运行了好6年了!现在我把它改成使用stackoverflow.com :) - Paul Dixon
我认为这个例子也不再适用了;现在对stackoverflow.com的HEAD请求会返回Content-Length - Nick Bartlett
显示剩余3条评论

15

是的,HEAD响应的Content-Length 应该 包含GET响应的Content-Length值(请参见@Paul's answer),但并不总是这样。

Stack Overflow会这样做:

> telnet stackoverflow.com 80
HEAD / HTTP/1.1
Host: stackoverflow.com


HTTP/1.1 200 OK
Cache-Control: public, max-age=60
Content-Length: 362245                           <--------
Content-Type: text/html; charset=utf-8
Expires: Mon, 04 Oct 2010 11:51:49 GMT
Last-Modified: Mon, 04 Oct 2010 11:50:49 GMT
Vary: *
Date: Mon, 04 Oct 2010 11:50:49 GMT

谷歌不会:

> telnet www.google.com 80
HEAD / HTTP/1.1
Host: www.google.ie


HTTP/1.1 200 OK
Date: Mon, 04 Oct 2010 11:55:36 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
Server: gws
X-XSS-Protection: 1; mode=block
Transfer-Encoding: chunked

1
我认为你看到的是由于未使用HTTP/1.0而导致的错误消息的内容长度。如果您发送正确的1.0 HEAD请求,则不会收到内容长度。我也在本地Apache实例上尝试了这个方法,同样没有返回内容长度。 - Paul Dixon
@Paul:我已经修复了我的错误请求。但是,我仍然会得到一个Content-Length,这是应该的。即使使用HTTP/1.0也是如此:http://i.imgur.com/iq9bm.jpg - Daniel Vassallo
是的,StackOverflow的IIS服务器确实会发送它。但Google却不会。 - Paul Dixon
1
@Paul:有趣。但 Google 并不会在接收到 200 响应时返回它。我在其他所有的返回码中都能看到它: 301、302、400 等等。感谢你找到了“SHOULD”的恰当定义 :) - Daniel Vassallo
你如何在nginx中添加头部? - Avishai

8

与被接受的答案相反,RFC 7231的4.3.2节指出:

服务器应该在响应HEAD请求时发送与GET请求相同的标头字段,除了有效载荷标头字段(第3.3节)

也就是说,Content-Length、Content-Range、Trailer和Transfer-Encoding可能会被省略。

这比Paul Dixon's answer中关于SHOULD的说明更加宽松

  1. MAY 这个词或形容词“OPTIONAL”表示该项是可选的。一个供应商可以选择包括该项,因为某个特定市场需要它或者因为供应商认为它能增强产品,而另一个供应商则可以省略相同的项。
所以真正的答案是,您不需要包含Content-Length,但如果您这样做,应该给出正确的值。

8

W3C的HTTP规范中指出:

如果新字段值表明缓存实体与当前实体不同(如Content-Length的更改所示...)

这意味着它应该保留与GET响应中相同的“正确”值。


0
根据2022年6月发布的最新HTTP规范RFC 9110 - HTTP语义,

服务器可以在响应HEAD请求(第9.3.2节)中发送Content-Length头字段;除非其字段值等于使用GET方法时响应内容将发送的八位字节的十进制数,否则服务器不得在此类响应中发送Content-Length。

服务器应该在响应HEAD请求时发送与GET请求相同的头字段。然而,服务器可以省略仅在生成内容时才确定值的头字段。例如,一些服务器会缓冲对GET的动态响应,直到生成了最小数量的数据,以便更有效地分隔小型响应或在内容选择方面做出晚期决策。这样对GET的响应可能包含Content-Length和Vary字段,但这些字段不会在HEAD响应中生成。这些轻微的不一致性被认为比为了HEAD请求而生成并丢弃内容更可取,因为通常请求HEAD是为了提高效率。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接