Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP 报文长什么样 #28

Open
18888628835 opened this issue May 20, 2021 · 0 comments
Open

HTTP 报文长什么样 #28

18888628835 opened this issue May 20, 2021 · 0 comments

Comments

@18888628835
Copy link
Owner

HTTP 报文长什么样

报文结构

TCP/UDP 的报文在传输的时候,都会加上头部数据,这个在上面我们已经讲过了。HTTP 协议也一样,会包装上一层数据,由于 HTTP 是超文本协议,那么实际上传输的很多东西并不需要经过解析,也可以肉眼看懂。

HTTP 请求报文和响应报文的结构基本相同,由三大部分组成

1.请求行(start line):描述请求或者响应的基本信息。

2.请求头(header):使用键值对的形式来表示表文

3.消息体(entity):实际传输的数据,有可能是纯文本,也可能是图片、视频等二进制数据。

其中请求行和请求头经常被合称请求头或者响应头。消息正文被称为“body”。

HTTP 协议规定报文必须有 header,但是可以没有 body,而且在 header 之后必须加一个空行。

image.png
在浏览器中他是这样的

image.png

这是一个请求报文:

它的第一行,是请求行,表示 GET 方式,基于 HTTP1.1版本

第二行是请求头,描述主机名、链接状态、接收方式等。

最后一行为空白行。后面没有 body

在发送 GET 请求的时候,允许没有 BODY。

虽然 HTTP 协议没有明确对 header 的大小做出限制,但是每个浏览器、Web 服务器都限制请求头以免太大可能影响运行效率。

请求行

请求行由三部分构成:

1.请求方法:是一个动词,如 GET/POST,表示对资源操作。

2.请求目标:通常是一个 URI,标记了请求方法要操作的资源。

3.版本号:表示采用的 HTTP 协议版本

这三个部分通常由空格分割,以换行CRLF结束。

image.png

在浏览器中是这样的

GET / HTTP/1.1 

GET 就是请求方发。紧接着的/是目标的根目录,意思是我要访问默认资源。最后是 HTTP 版本。

状态行

状态行是在响应报文里面运行的,你也可以叫响应行,但是它也有个标准名字--状态行。意思是服务器响应的状态。

状态行分成三个部分:

1.版本号:表示报文使用的 HTTP 版本

2.状态码:一个三位数,用数字的形式表示处理的结果,比如200是成功,500是服务器错误。

3.原因:作为数字状态的补充,是更加详细的解释文字,比如帮助别人理解原因。

image.png
在浏览器中,它可能是这样的

HTTP/1.1 200 OK

意思是基于 HTTP1.1版本的请求,状态码是200,一切 ok。

还有可能是这样的

HTTP/1.1 404 Not Found

意思是404状态码,没有找到对应的资源。

头部字段

请求行或状态行加上头部字段的集合就构成了 HTTP 完整的请求头或者响应头

image.png

image.png

请求头和响应头的结构是一样的,唯一的区别是起始行。

头部字段分为 key-value 的形式,之间使用:分割,最后以换行结束。比如“Host: 127.0.0.1”这一行里 key 就是“Host”,value就是“127.0.0.1”。

HTTP 字段非常灵活,不仅可以采用诸如 Host的标准字段,还可以使用任意的字段。所以扩展性非常强。

不过也需要注意一些细节:

  1. 字段名不区分大小写,例如“Host”也可以写成“host”,但首字母大写的可读性更好;

  2. 字段名里不允许出现空格,可以使用连字符“-”,但不能使用下划线“_”。例如,“test-name”是合法的字段名,而“test name”“test_name”是不正确的字段名;

  3. 字段名后面必须紧接着“:”,不能有空格,而“:”后的字段值前可以有多个空格;

  4. 字段的顺序是没有意义的,可以任意排列不影响语义;

  5. 字段原则上不能重复,除非这个字段本身的语义允许,例如 Set-Cookie。

常用头字段

HTTP 协议有非常多的头字段,可以实现各种功能,总体分为四大类:

1.通用字段:请求头或者响应头都可以出现。

2.请求字段:仅能够出现在请求头里,进一步说明请求信息或者额外条件。

3.响应字段:仅出现在响应头里,补充说明响应报文信息。

4.实体字段:也属于通用字段,描述 body 的额外信息。

下面来说几个常用字段

  • Host 字段:HTTP1.1中规定的必须出现的字段,表示告诉服务器这个请求应该让哪个主机处理。

  • User-Agent字段:请求字段,只在请求头中出现,表示发起请求的客户端。

  • Date 字段:通用字段,通常出现在响应头中,表示 HTTP 创建的时间。

  • Server 字段:响应字段,只出现在响应头中,它告诉客户端当前正则提供 Web 服务的软件名称和版本号。这个字段会把服务器的一部分信息暴露给外界,所以有可能引起黑客攻击,所以允许没有,或者给一段完全无关的描述信息。

在 github中,这个字段就没有告诉我们使用Apache 还是 Nginx。

image.png

  • Content-Length字段:表示 Body 的长度,这是实体字段。告诉服务器有多少数据需要接收。

小结

HTTP 报文由起始行+头部+空行+实体组成,简单来说就是 header+body

HTTP 报文可以没有 body,但是必须有header 和空行。

请求头由请求行+头部字段组成,响应头由状态行+头部字段组成

请求行由请求方法、请求目标、版本号组成

状态行由状态码,附加信息,版本号组成

头部字段采用 key:value 形式,不拘束大小写,不存在顺序问题,还可以自定义字段,实现随意扩展的功能。

HTTP1.1中,必须出现 HOST 字段,它必须出现在请求头中,表示对方的主机名

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant