HTTP协议入门指南
一、HTTP 协议
1.1 HTTP 是什么?
通俗来讲,它就是计算机通过网络进行通信的规则,是一个基于客户端请求与服务器端响应,无状态的基于TCP/IP协议传输数据的应用层(应用层可以理解为是由具体)协议。目前任何终端(手机,笔记本电脑。。)之间进行任何一种通信都必须按照HTTP协议进行,否则无法连接。
1.2 HTTP 是无状态的
HTTP 协议对于事务处理没有记忆能力,客户端第一次与服务器建立连接发送请求时需要进行一系列的安全认证匹配(三次握手)等。当客户端向服务器端发送请求,服务器端响应完毕后,两者断开连接,也不保存连接状态,一刀两断!恩断义绝!从此路人!下一次客户端向同样的服务器发送请求时,由于他们之前已经遗忘了彼此,所以每次都是建立一个全新的连接。
1.3 HTTP 是应用层的
应用层通俗来讲,就是并非是计算机底层写死的,而是各个应用根据协议规范而实现的;比如浏览器对HTTP的支持是由浏览器实现的;同时绝大多数编程语言也都内置或通过功能库实现了对HTTP协议的支持;当大家都遵循HTTP协议规范时,那么各自就能对应的识别及解析HTTP协议下的数据内容;
1.4 HTTP 是基于TCP/IP底层协议的
HTTP 使用TCP通信作为它的支撑运输协议(TCP是底层协议,是计算机底层实现,由应用层调用)。HTTP 客户机发起一个与服务器的 TCP 连接,一旦连接建立,浏览器(客户机)和服务器进程就可以通过套接字接口访问 TCP。
二、HTTP 请求报文
一个HTTP请求报文由请求行(request line)、请求头(request header)、空行和请求体(request body)4个部分组成。
下图给出了请求报文的规范格

TTP请求报文就是一段规范格式的文本(文本,文本,文本,重要的说三遍);
所谓的发送JSON请求,表单请求,并不是指发送的请求报文是JSON或表单,而是指将JSON或表单等格式的文本数据,放在请求报文的请求体中; 这些说法本质上是告知服务端的开发人员应当以什么样的方式来解析请求体内的数据; 切记:HTTP传输数据其本质就是传输符合上图格式的文本。
2.1 请求行
请求行分为三个部分:请求方法、请求地址和协议版本
2.1.1 请求方法
HTTP/1.1 定义的请求方法有8种:
GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。最常的有两种:
GET和POST。如果是 RESTful 接口的话一般会用到:
GET(查)、POST(改)、DELETE(删)、PUT(增)。
2.1.2 请求地址
URL: 统一资源定位符,对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。
互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它等。
组成:<协议>://<主机>:<端口>/<路径>?<参数名>=<参数值>&<参数名>=<参数值>
端口和路径有时可以省略(HTTP 默认缺省端口号是80)

2.1.3 协议版本
协议版本的格式为:HTTP/<主版本号>.<次版本号>,常用的有HTTP/1.0和HTTP/1.1
2.2 请求头
请求头为请求报文添加了一些附加信息,由键/值对组成,每行一对,名和值之间使用冒号分隔。
请求头的最后会有一个空行,表示请求头部结束,接下来为请求数据,这一行非常重要,必不可少。
常见请求头如下(更多详情可查看 Mozilla 官方说明):
注意:浏览器一般会在发起请求时,默认自带一些请求头,一般包括Host,User-Agent,Accept-Language,Connection等。包括其他会发起HTTP请求客户端,也都会默认传输一些请求头(某些客户端如果开发者没有定义则传输默认的,如果定义了则传输开发者设定的值)。
3.3 请求体
请求体或者说请求数据是可选的部分,比如GET请求没有请求体。一般Json数据,表单数据都会放在请求体中进行传递。
下面是一个POST方法的请求报文:
POST /index.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2 请求头
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost/
Content-Length:25
Content-Type:application/x-www-form-urlencoded
username=aa&password=1234三、HTTP 响应报文
HTTP响应报文主要由状态行(response line)、响应头(response head)、空行以及响应正文(response body)4个部分组成。
下图给出了相应报文的规范格式:

3.1 状态行
由 3 部分组成,分别为:协议版本,状态码,状态码描述。
其中协议版本与请求报文一致,状态码描述是对状态码的简单描述,所以这里就只介绍状态码。
3.2 状态码:
状态代码为3位数字。 1xx:指示信息--表示请求已接收,继续处理。 2xx:成功信息--表示请求已被成功接收、理解、接受。 3xx:重定向--要完成请求必须进行更进一步的操作。 4xx:客户端错误--请求有语法错误或请求无法实现。 5xx:服务器端错误--服务器未能实现合法的请求。
下面列举几个常见的:
3.3 响应头
与请求头类似,为响应报文添加了一些附加信息;
常见响应头部如下:
3.4 响应数据/响应正文
用于存放需要返回给客户端的数据信息。
下面是一个响应报文的实例:
HTTP/1.1 200 OK
Date: Sun, 17 Mar 2022 08:12:54 GMT
Server: Apache/2.2.8 (Win32) PHP/5.2.5
X-Powered-By: PHP/8.1.8
Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 4393
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
<html><head><title>HTTP响应示例<title></head><body>Hello HTTP!</body></html>注意:和 HTTP 请求报文一样,响应报文也是一段规范格式的文本,文本,文本(详见响应报文格式图); 所谓服务器端返回了 Json,其实际含义是,响应报文中正文的数据格式是一段Json文本。客户端工程师可以对响应正文进行 Json 解析。
四、一切都是文本
HTTP 报文综上所述就是一个被约定了格式的文本;不存在Json, 整数,浮点数这些编程语言中的语法概念;
无论客户端或服务器端,在对应的编程中进行处理时获取的请求头,请求数据,响应头,响应数据等,虽然看上去你直接获取到了请求头字典,Json字典;甚至你还特意去判断这些内容的数据类型,并且的确不是文本;这可能让你很迷惑,HTTP 报文不是说全部是文本吗?
原因是:由于HTTP 报文格式是约定俗称的标准,进而绝大多数编程语言及基础 HTTP 功能库已经实现了HTTP 报文的格式解析,甚至会自动识别Content-Type,并根据格式类型解析成对应编程语言内的数据类型,而不是让你再去解析一遍(编程,编程,永远是让重复的事情不用重复的做)。
所以,你在使用时,是基于对应语言,工具或功能库解析后进行HTTP相关操作。 而不是直接处理原始 HTTP 报文。