 
 
前言
HTTP协议——互联网发展的基石,从一个最简单的“helloworld”网页,到现在博客平台、视频网站都离不开HTTP协议的存在。随着互联网的发展,Web网页的设计也越发复杂,前后端开发的分工也越发明确,HTTP作为连接前后端的桥梁,只有掌握它才能更好地实现前后端数据交接。
HTTP协议基础
概念
HTTP(HyperText Transfer Protocol,超文本传输协议),工作于TCP/IP协议族中的应用层,基于TCP协议来提供服务,是互联网发展基石般的存在,用于浏览器与远端服务器的通信,并获取其内部资源,如:网页html、图片等。
HTTP是无状态协议,也就是说服务器不会保存每次请求的信息。对于服务器来讲,每次连接都是独立的,所有连接一视同仁。这样设计简化了服务器的设计与压力,但在需要保存状态的情况(如登录信息、历史记录等),则需要使用cookie、session等手段来实现个性化服务。

HTTP的工作流程
HTTP是基于CS模型的一种通信协议,通信过程中必定由客户端(浏览器)先发起请求,服务器进行响应(返回网页信息)。

HTTP协议在通信时的流程
-  发起DNS请求:HTTP协议在向远端服务器发起请求前,会先向DNS服务器请求域名所对应的IP地址。 
-  建立TCP连接:获取到IP地址后,与远端服务器建立连接(三次握手)。 
-  客户端发送请求:建立好连接后,客户端向服务器发送一个HTTP请求。 
-  服务器响应请求:服务器收到请求后,根据请求内容发送响应报文 
-  显示网页:客户端收到响应报文,解析数据,显示到网页当中。 
HTTP协议格式
HTTP协议中报文分为两类:请求报文与响应报文,但他们的报文格式都是通用的,即报头首行 + 头部字段 + 空行 + 报文数据(可选)。

报文格式:
-  请求报文 -  请求行:包含请求方法,HTTP版本。 
-  头部字段:包含通用字段 + 请求字段。 
-  空行:固定格式,用于区分报头与报文。 
-  报文数据(可选):请求报文一般没有报文数据。 
 
-  
-  响应报文 -  状态行:包含请求的状态码、原因,HTTP版本。 
-  头部字段:包含通用字段 + 响应字段。 
-  空行:固定格式。 
-  报文数据(可选):返回请求的资源,可以是html、图片、js等。 
 
-  
报头首行
请求行
请求行包含请求方法、请求URI与HTTP版本,例如:
GET / HTTP/1.1    # 请求行
User-Agent: PostmanRuntime/7.39.0
Accept: */*
Postman-Token: bf247d0a-a311-41c1-a739-29bdeb43d0fb
Host: localhost:8080
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
常用请求首部方法
| 请求方法 | 描述 | 
|---|---|
| GET | 请求指定资源的表示形式。GET请求应当只用于获取数据,而不应对服务器产生任何副作用。 | 
| POST | 向指定资源提交数据进行处理。数据包含在请求体中。POST请求可能会导致服务器状态的改变或者副作用。 | 
| PUT | 向指定资源位置上传其最新内容。PUT请求会用请求中的数据替换目标资源的全部内容。 | 
| DELETE | 请求服务器删除请求的指定资源。 | 
| HEAD | 类似于GET请求,但只请求资源的首部信息,不返回具体内容。通常用于检查资源的有效性或获取资源的元数据。 | 
| OPTIONS | 请求指定资源的通信选项和可用方法。可以用于检查服务器支持哪些HTTP方法。 | 
| PATCH | 对资源进行部分修改。PATCH请求包含的实体中,通常只包括修改的部分,而不是资源的全部内容。 | 
状态行
状态行包含HTTP版本、状态码、原因,例如:
HTTP/1.1 200 OK       #状态行
Date: Fri, 14 Jun 2024 13:04:10 GMT
Server: Apache
Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT
ETag: "51-47cf7e6ee8400"
Accept-Ranges: bytes
Content-Length: 81
Cache-Control: max-age=86400
Expires: Sat, 15 Jun 2024 13:04:10 GMT
Connection: Keep-Alive
Content-Type: text/html
状态码类别
| 状态码类别 | 含义 | 
|---|---|
| 1xx 信息性状态码 | 接收的请求正在处理。 | 
| 2xx 成功状态码 | 请求已被成功接收、理解和处理。 | 
| 3xx 重定向状态码 | 需要进一步操作以完成请求。 | 
| 4xx 客户端错误状态码 | 客户端存在问题。 | 
| 5xx 服务器错误状态码 | 服务器在处理请求时遇到错误。 | 
常见状态码
| 状态码 | 原因 | 描述 | 
|---|---|---|
| 200 | OK | 请求被正确处理 | 
| 201 | Created | 请求成功并创建了新的资源 | 
| 204 | No Content | 请求成功但没有内容返回 | 
| 301 | Moved Permanently | 永久重定向,资源已永久移动到新URL | 
| 302 | Found | 资源暂时位于不同的URL | 
| 400 | Bad Request | 请求由于语法错误无法被理解 | 
| 401 | Unauthorized | 客户端必须进行身份验证才能获得请求的响应 | 
| 403 | Forbidden | 客户端无权访问内容 | 
| 404 | Not Found | 服务器找不到请求的资源 | 
| 500 | Internal Server Error | 服务器遇到无法处理的情况 | 
| 502 | Bad Gateway | 服务器作为网关时收到无效响应 | 
| 503 | Service Unavailable | 服务器无法处理请求 | 
| 504 | Gateway Timeout | 服务器作为网关时没有及时收到响应 | 
首部字段
首部字段是HTTP协议用于控制HTTP运作方式的要素之一,可以将其当成HTTP的额外选项。
首部字段分为三类
-  通用首部字段:无论是响应报文还是请求报文都可以使用的选项。 
-  响应/请求首部字段:仅可以在响应/请求报文中使用的字段。 
-  实体首部字段:实体首部字段虽然可以在HTTP请求和响应中使用,但其专注于为报文的消息体提供服务。 
通用首部字段
| 首部字段 | 描述 | 
|---|---|
| Cache-Control | 指示请求或响应的缓存机制,用于控制缓存的存储和检索方式。 | 
| Connection | 控制当前连接的选项。常用值包括 keep-alive(保持连接)和close(关闭连接)。 | 
| Date | 指示消息发送的日期和时间,格式为RFC 1123日期格式。 | 
| Pragma | 包含实现特定的指令,主要用于向后兼容HTTP/1.0。常见值为 no-cache,用于防止缓存。 | 
| Trailer | 指定在消息末尾可能出现的字段,用于分块传输编码。 | 
| Transfer-Encoding | 指示传输消息体的编码方式,例如 chunked(分块传输编码)。 | 
| Upgrade | 用于向服务器或客户端发出协议升级请求,通常用于HTTPS或HTTP/2升级。 | 
| Via | 显示报文经过的中间节点(代理服务器或网关),用于追踪请求或响应的路径。 | 
| Warning | 传达与缓存相关的警告信息,告知客户端可能存在的缓存问题。 | 
请求/响应首部字段
响应首部字段
| 首部字段 | 描述 | 
|---|---|
| Accept-Ranges | 指示服务器是否支持字节范围请求(partial requests),如 bytes。 | 
| Age | 响应在缓存中存储的时间,以秒为单位。 | 
| ETag | 资源的实体标签,服务器用来标识资源的特定版本。 | 
| Location | 指示客户端重定向到的URL,用于3xx状态码的响应。 | 
| Proxy-Authenticate | 指示客户端需要进行代理身份验证的信息。 | 
| Retry-After | 指示客户端应在多长时间后再次尝试请求,用于5xx状态码的响应。 | 
| Server | 包含服务器软件的信息。 | 
| Vary | 指示缓存服务器使用的请求头,以区分不同的响应。 | 
| WWW-Authenticate | 指示客户端如何进行身份验证,以便访问资源。 | 
| Set-Cookie | 发送会话cookie到客户端。 | 
| Content-Location | 给出实际访问的资源的URL。 | 
请求首部字段
| 首部字段 | 描述 | 
|---|---|
| Accept | 指定客户端能够处理的内容类型。 | 
| Accept-Charset | 指定客户端能够接收的字符集。 | 
| Accept-Encoding | 指定客户端能够处理的内容编码。 | 
| Accept-Language | 指定客户端能够处理的自然语言。 | 
| Host | 指定请求的目标主机名和端口号,必须包含在HTTP/1.1请求中。 | 
| User-Agent | 包含发出请求的用户代理信息(如浏览器类型、版本等)。 | 
| Authorization | 包含客户端为获取资源进行身份验证的信息。 | 
| Cache-Control | 用于指定请求和响应遵循的缓存机制。 | 
| Connection | 控制当前连接的选项,例如 keep-alive和close。 | 
| Cookie | 包含客户端之前收到的并存储在客户端上的Cookie。 | 
| Content-Length | 在POST请求中,表示请求体的长度(以字节为单位)。 | 
| Content-Type | 在POST请求中,表示请求体的媒体类型。 | 
| Date | 发送请求的日期和时间。 | 
| Expect | 指定客户端要求服务器满足的特定行为。 | 
| If-Match | 仅在客户端提供的ETag值与资源的ETag值匹配时才执行请求。 | 
| If-Modified-Since | 仅在请求的资源自指定日期后被修改过时才返回资源。 | 
| If-None-Match | 仅在请求的资源的ETag值与客户端提供的不匹配时才返回资源。 | 
| If-Range | 仅在请求的资源自指定日期后被修改过时才返回部分资源。 | 
| If-Unmodified-Since | 仅在请求的资源自指定日期后未被修改过时才执行请求。 | 
| Range | 请求返回资源的部分内容,指定字节范围。 | 
| Referer | 指定请求资源的来源页面。 | 
实体首部字段
| 首部字段 | 描述 | 
|---|---|
| Allow | 列出资源支持的HTTP请求方法。 | 
| Content-Encoding | 指示对实体进行的编码类型,用于标识实体数据被压缩的方式。 | 
| Content-Language | 描述资源的自然语言,例如 en表示英语。 | 
| Content-Length | 指定实体主体的大小,以字节为单位。 | 
| Content-Location | 给出请求资源的替代位置,通常是一个URL。 | 
| Content-MD5 | 包含实体主体的MD5校验和,用于检查数据完整性。 | 
| Content-Range | 指示实体主体中部分内容的位置,用于部分请求。 | 
| Content-Type | 指定实体主体的媒体类型,例如 text/html。 | 
| Expires | 指定实体主体过期的日期和时间,用于缓存控制。 | 
| Last-Modified | 指示资源最后修改的日期和时间。 | 
HTTP状态管理
HTTP是无状态的协议,这意味这服务器无法区分每个连接之间的区别,但实际上的网页服务上总是能见到用户登录、购物车等需要状态管理的内容。于是HTTP引入cookie、session等功能来实现数据的持久化状态管理。
Cookie与session
Cookie
Cookie 是一种存储在客户端中的小型数据文件,由服务器生成并发送给客户端。客户端每次访问该服务器时,都会自动携带相应的Cookie信息。服务器通过检索Cookie信息,从而给拥有不同Cookie的请求提供不同的服务。

 工作流程
-  客户端发送请求(无Cookie)。 
-  服务器设置Cookie信息。 
-  客户端接收并存储Cookie信息。 
-  客户端发送含有Cookie的报文。 
cookie的结构
| 字段名称 | 描述 | 
|---|---|
| Name | Cookie的名称,唯一标识这个Cookie。 | 
| Value | Cookie的值,与名称一起构成键值对。 | 
| Domain | 指定Cookie适用的域。浏览器将只发送此Cookie到该域名或其子域名。 | 
| Path | 指定Cookie适用的路径。浏览器将只发送此Cookie到该路径及其子路径。 | 
| Expires/Max-Age | 指定Cookie的过期时间。 Expires使用具体的日期和时间表示,而Max-Age使用相对时间(以秒为单位)表示。 | 
| Secure | 指定Cookie仅通过HTTPS连接发送,增加了Cookie的安全性。 | 
| HttpOnly | 指定Cookie不能被JavaScript访问,减少XSS攻击的风险。 | 
| SameSite | 控制Cookie在跨站请求时的行为,有三个值: Strict、Lax、None,用于防范CSRF攻击。 | 
Session
Session 是存储于服务器中的数据,用于保持用户的会话状态。每个Session都有一个唯一的Session ID,服务器通过这个ID来识别和管理用户的会话信息。

工作流程
-  客户端通过POST方法发送用户信息(username + passwd)给服务器。 
-  服务器检查信息,创建一个SessionID,并使用Set-Cookie字段发送给客户端 
-  客户端存储Cookie信息,在之后的请求中,于报头增添Cookie信息。 
总结
HTTP是基于CS模型的无状态传输协议,拥有两种报文格式——请求报文/响应报文,其通过报头的首部字段来进行额外配置,能够通过配合Cookie、Session等方式实现持久化状态管理。
📜博客主页:主页
📫我的专栏:C++
📱我的github:github
