为GET请求设置的正确Content-Length是什么?

mer*_*011 15 http httpwebrequest content-length http-headers

当我POST使用以下代码发出请求时:

string body = "Hello World";
byte[] bytes = Encoding.ASCII.GetBytes(body);
WebRequest request = WebRequest.Create("http://internalurl");
request.Method = "POST";
request.ContentLength = bytes.Length;
Run Code Online (Sandbox Code Playgroud)

我将内容长度设置为POSTed 的字节数.请求的正确性ContentLengthGET什么?

Fil*_*efp 28

由于您在执行GET请求时通常不会发送任何其他数据,Content-Length因此根本不应发送标头.

Content-Length只有在发送消息体时才应包含标头,并且所讨论的标头的值始终是此字段的长度,以(OCTETs)字节为单位.

(RFC2616)14.13内容长度

内容长度实体头字段指示实体主体的大小,以字节为单位的十进制数,发送到接收方,或在HEAD方法的情况下,这将被发送的实体主体的大小有请求是GET.

<snip />

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


在执行请求时,(AFAIK)认为包含消息体的不良做法GET,但在阅读HTTP RFC2616时,我没有看到任何声明GET请求不能包含消息体.

虽然我会假设今天的大多数Web服务器都不会回复您希望他们回复的内容,如果您在消息体中发送数据并希望在这种情况下解析和处理它.

(RFC2616)4.3消息正文

HTTP消息的消息体(如果有的话)用于携带与请求或响应相关联的实体体.只有当应用了传输编码时,消息体才与实体体不同,如Transfer-Encoding头字段所示(第14.41节).

   message-body = entity-body
                | <entity-body encoded as per Transfer-Encoding>
Run Code Online (Sandbox Code Playgroud)

传输编码必须用于指示应用程序应用的任何传输编码,以确保安全和正确地传输消息.Transfer-Encoding是消息的属性,而不是实体的属性,因此可以由请求/响应链中的任何应用程序添加或删除.(但是,第3.6节限制了何时可以使用某些转移编码.)

消息中允许消息正文的规则因请求和响应而异.

通过在请求的消息头中包含Content-Length或Transfer-Encoding头字段来指示请求中消息体的存在.

如果请求方法的规范(第5.1.1节)不允许在请求中发送实体主体,则消息主体不得包含在请求中.

服务器应该在任何请求上读取和转发消息体; 如果请求方法不包含实体主体的定义语义,那么在处理请求时应该忽略消息主体.

  • https://tools.ietf.org/html/rfc7230 RFC7230 现在明确表示“当请求消息不包含有效负载主体并且方法语义不预期这样的主体时,用户代理不应发送 Content-Length 标头字段”。 (3认同)
  • 这个答案的小补充:[RFC7231](https://tools.ietf.org/html/rfc7231#section-4.3.1)(新的RFC723x系列RFC的一部分,废弃了“旧”RFC2616)只是说`GET 请求消息中的有效载荷没有定义的语义;在 GET 请求上发送有效负载正文可能会导致某些现有实现拒绝该请求。` (2认同)