文章目录
- 1.HTTP简介
- 2.HTTP报文的结构
- 3.HTTP协议中空行的作用
- 4.uri和url的区别
- 5.HTTP请求
-
- [5.1 HTTP请求方法](#5.1 HTTP请求方法)
- [5.2 HTTP请求报头](#5.2 HTTP请求报头)
- 6.HTTP响应
-
- [6.1 状态码](#6.1 状态码)
- 7.HTTP位于应用层(基于TCP)
- 8.非持久和持久连接
-
- [8.1 非持久连接](#8.1 非持久连接)
- [8.2 持久连接](#8.2 持久连接)
1.HTTP简介
HTTP(Hypertext Transfer Protocol)即超文本传输协议,是互联网上应用最为广泛的一种网络协议,主要用于从WWW服务器传输超文本到本地浏览器的传输协议。它是基于客户端-服务器模型的,目的是允许浏览器(或其他HTTP客户端)从Web服务器请求资源,并且服务器能够将这些资源传回给客户端。
主要特性:
- 无状态:HTTP协议是无状态的,这意味着每个请求都是独立的,服务器不保留关于客户的任何信息(如 cookies 可以用来维护会话状态)。
- 媒体独立:可以传输任意类型的数据对象,不限于文本,图像、视频等多媒体文件同样可以传输。
- 简单快速:客户端向服务器请求服务时,只需传送请求方法和路径。常用的方法有GET、POST等。
- 灵活:HTTP允许传输数据的内容类型多样,通过Content-Type加以标记。
- 无连接:限制每次连接只处理一个请求,之后连接就会关闭,但实际应用中常通过Keep-Alive机制保持连接打开,以便多个请求复用。
2.HTTP报文的结构
大家应该都听说过HTTP请求和HTTP响应.因此HTTP报文也分为请求报文和响应报文,但是请求报文和响应报文的结构是一样的.
如图:
请求报文和响应报文虽然结构是一样的,但是报文首部是不同的
在请求报文中,HTTP报文首部是由方法,URI,HTTP版本和HTTP首部字段构成
在响应报文中,HTTP报文首部是由HTTP版本,状态码和HTTP首部字段构成
3.HTTP协议中空行的作用
因为 HTTP 协议并没有规定报头部分的键值对有多少个. 空行就相当于是 "报头的结束标记", 或者
是 "报头和正文之间的分隔符".
HTTP 在传输层依赖 TCP 协议, TCP 是面向字节流的. 如果没有这个空行, 就会出现 "粘包问题".
4.uri和url的区别
URI(Uniform Resource Identifier,统一资源标识符)和URL(Uniform Resource Locator,统一资源定位符)都是用于标识网络资源的字符串,但它们在概念和用途上有所区别:
- URI 是一个更广泛的概念,它是用于标识互联网上或计算机系统中任何资源的字符串。URI 包括了定位资源的地址(即URL),也包括仅用于命名或识别资源但不提供直接访问方式的标识符(例如URN,Uniform Resource Name)。URI 的目的是确保每一个资源都有一个唯一的标识,无论这个资源是可以获取的还是仅仅被命名的。
- URL 是 URI 的一个子集,它是一种特定类型的 URI,不仅标识了资源,还提供了定位和访问该资源的方法。URL 包含了访问资源所需的全部信息,比如协议类型(http、https)、主机名、路径(/path/to/resource)以及可能的查询字符串(?key=value)等。简而言之,当你能通过某个地址在互联网上找到一个资源时,那个地址就是一个以及可能的查询字符串(?key=value)等。简而言之,当你能通过某个地址在互联网上找到一个资源时,那个地址就是一个) URL。
总结来说,所有 URL 都是 URI,因为它们都能标识资源,但不是所有的 URI 都是 URL,有的 URI 只是用来命名资源而不提供定位信息(例如URN)。在实际应用中,我们通常所说的网址就是 URL,它是 URI 实际应用中最常见的一种形式。
5.HTTP请求
5.1 HTTP请求方法
HTTP协议定义了一系列请求方法,用于指示客户端希望服务器对资源执行的操作。以下是HTTP/1.1中定义的8种主要请求方法,每种方法都有其特定的用途和特点:
- GET :用于请求指定的资源。请求的数据会附加在URL(
query string
)之后,以查询字符串的形式传递。GET请求是最常见的,用于获取资源,应是安全和幂等的。 - POST :用于向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据包含在请求正文(
body
)中,POST请求不是幂等的,多次请求可能会产生不同结果。 - PUT:用于替换指定资源的全部内容。客户端提供更新后的资源,要求服务器存储。此方法是幂等的,多次执行具有相同效果。
- DELETE:请求服务器删除指定的资源。此方法也是幂等的,多次请求删除同一资源的结果是一致的。
- HEAD:类似于GET方法,但服务器只返回响应头,不返回响应主体,用于检查资源的存在性、类型、大小等元数据,而不需要传输整个内容。
- OPTIONS:用于获取服务器支持的HTTP请求方法和其他通信选项,可用于检测服务器功能或测试权限。
- TRACE:客户端发送一个请求,服务器会将收到的请求原样返回,主要用于诊断和测试目的,查看请求在到达服务器前经过的路径上的改动。
- CONNECT:用于建立一个到由目标资源标识的服务器的TCP连接通道,通常用于代理服务器中,实现对HTTPS等需要通过隧道协议进行安全传输的请求。
关于Query String和Param(Parameters)
-
查询字符串(Query String)是指URL中跟在问号(?)后面的部分,用于携带额外的信息,特别是作为HTTP GET请求的一部分传递参数给服务器。它由一系列键值对组成,键值对之间用等号(=)连接,不同的键值对之间用和号(&)分隔。例如,在URL
https://example.com/search?q=query+term&sort=date
中,q=query+term
和sort=date
就是查询字符串中的两个参数。 -
参数(Params)是查询字符串中具体键值对的统称。在上述例子中,
q
和sort
是参数名,query+term
和date
是对应的参数值。这些参数让服务器知道客户端请求的具体细节,比如搜索关键词、排序方式等。
5.2 HTTP请求报头
HTTP请求报头(Request Headers)是一系列键值对,位于请求行之后,请求主体之前,每一行代表一个报头字段。
以下是我用Fiddler抓的一个包
具体内容如下:
http
GET https://www.baidu.com/ HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
sec-ch-ua: "Chromium";v="124", "Microsoft Edge";v="124", "Not-A.Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie: BIDUPSID=DD7326D9CB3E780AE232E272F9988EF1; PSTM=1700320963; BAIDUID=CB65E88DF6D23B274067D86F39E33F91:FG=1; H_WISE_SIDS=40171_40369_40376_40398_40416_40305_40458_39662_40511_40512_60044_60026_60035_60048_60058; H_WISE_SIDS_BFESS=40171_40369_40376_40398_40416_40305_40458_39662_40511_40512_60044_60026_60035_60048_60058; BAIDUID_BFESS=CB65E88DF6D23B274067D86F39E33F91:FG=1; COOKIE_SESSION=130_0_8_3_5_14_1_1_8_6_1_3_56_0_0_0_1713166585_0_1713181572%7C9%23580281_10_1665372810%7C4; BAIDU_WISE_UID=wapp_1713714319309_20; H_PS_PSSID=40305_40080_60138_60186; BDUSS=2R5UzNPZzZ3ai1kNVlXcEZjVWc4ZnctT3ZVRmdGQllvOXpCb0JZNGljanFmMWxtRVFBQUFBJCQAAAAAAAAAAAEAAAA1MYH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOryMWbq8jFmc; BDUSS_BFESS=2R5UzNPZzZ3ai1kNVlXcEZjVWc4ZnctT3ZVRmdGQllvOXpCb0JZNGljanFmMWxtRVFBQUFBJCQAAAAAAAAAAAEAAAA1MYH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOryMWbq8jFmc; ZFY=DAt6xuFJrVO9Vof3C8Wq3xMauOxCp4CYAj4HYxdRdyg:C
第一行GET https://www.baidu.com/ HTTP/1.1
是方法,URI,HTTP版本.就不多说了
Host: www.baidu.com
:请求的服务器的域名和(可选的)端口号,用于虚拟主机的识别。没写端口就是默认值- HTTP默认端口是80
- HTTPS默认端口是443
Content-Length和Content-Type在请求中不一定存在(请求没有body(GET请求)情况下就不存在),像上面我抓的这个包就是GET请求,里面就没有这两个字段.它们俩是成对出现的,只要有其中一个,另一个必定存在.
- Content-Length: 当请求包含实体内容时,表示实体内容的字节大小,有助于服务器正确处理请求体。
- Content-Type : 描述请求主体的MIME类型,如
application/x-www-form-urlencoded
表示表单数据,multipart/form-data
用于文件上传。application/json
表示数据为 json 格式
- User-Agent: 客户端的用户代理信息,包括浏览器类型、版本、操作系统等,帮助服务器提供定制化的响应或统计分析。
http
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0
分析图:
-
Referer: 发起请求的页面地址,用于追踪用户是从哪个页面链接过来的。这个在HTTP请求头中可有可没有
-
Cookie: 发送给服务器的Cookie信息,用于维持用户会话状态或个性化设置,是浏览器本地数据存储的一种机制。
http
Cookie: BIDUPSID=DD7326D9CB3E780AE232E272F9988EF1; PSTM=1700320963; BAIDUID=CB65E88DF6D23B274067D86F39E33F91:FG=1; H_WISE_SIDS=40171_40369_40376_40398_40416_40305_40458_39662_40511_40512_60044_60026_60035_60048_60058; H_WISE_SIDS_BFESS=40171_40369_40376_40398_40416_40305_40458_39662_40511_40512_60044_60026_60035_60048_60058; BAIDUID_BFESS=CB65E88DF6D23B274067D86F39E33F91:FG=1; COOKIE_SESSION=130_0_8_3_5_14_1_1_8_6_1_3_56_0_0_0_1713166585_0_1713181572%7C9%23580281_10_1665372810%7C4; BAIDU_WISE_UID=wapp_1713714319309_20; H_PS_PSSID=40305_40080_60138_60186; BDUSS=2R5UzNPZzZ3ai1kNVlXcEZjVWc4ZnctT3ZVRmdGQllvOXpCb0JZNGljanFmMWxtRVFBQUFBJCQAAAAAAAAAAAEAAAA1MYH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOryMWbq8jFmc; BDUSS_BFESS=2R5UzNPZzZ3ai1kNVlXcEZjVWc4ZnctT3ZVRmdGQllvOXpCb0JZNGljanFmMWxtRVFBQUFBJCQAAAAAAAAAAAEAAAA1MYH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOryMWbq8jFmc; ZFY=DAt6xuFJrVO9Vof3C8Wq3xMauOxCp4CYAj4HYxdRdyg:C
我们也可以在浏览器中看到有哪些cookie数据
请求报头有很多,还有其它的一些如下所示:
- Accept : 指定客户端能够接收的内容类型(MIME类型),例如
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
,表示优先接收HTML,然后是XML,最后是任何类型。 - Accept-Encoding: 客户端支持的内容编码方式,如gzip、deflate等,用于请求压缩内容以减少传输量。
- Accept-Language : 客户端期望接收的内容语言,如
en-US,en;q=0.5
表示首选英语(美国),其他英语也接受,但优先级较低。 - Authorization : 用于HTTP身份验证,包含用户的认证信息,如
Basic YWxhZGRpbjpvcGVuc2VzYW1l
或Bearer your_token_here
。 - Cache-Control : 控制请求和响应的缓存机制,如
no-cache
表示不要使用缓存副本,必须从服务器重新获取。 - Connection : 指示对于当前事务完成后,是否关闭网络连接还是继续保持打开状态,如
keep-alive
表示持久连接。 - If-Modified-Since: 客户端缓存的资源最后修改时间,询问服务器资源是否有更新,用于条件请求。
6.HTTP响应
下图是刚才HTTP请求的响应报文
内容如下:
http
HTTP/1.1 200 OK
Connection: keep-alive
Content-Encoding: gzip
Content-Security-Policy: frame-ancestors 'self' https://chat.baidu.com http://mirror-chat.baidu.com https://fj-chat.baidu.com https://hba-chat.baidu.com https://hbe-chat.baidu.com https://njjs-chat.baidu.com https://nj-chat.baidu.com https://hna-chat.baidu.com https://hnb-chat.baidu.com http://debug.baidu-int.com;
Content-Type: text/html; charset=utf-8
Date: Fri, 10 May 2024 07:14:05 GMT
Isprivate: 1
Server: BWS/1.1
Set-Cookie: H_PS_PSSID=40305_40080_60138_60237_60270_60275; path=/; expires=Sat, 10-May-25 07:14:05 GMT; domain=.baidu.com
Traceid: 1715325245044552423416257137435173222985
X-Ua-Compatible: IE=Edge,chrome=1
X-Xss-Protection: 1;mode=block
Transfer-Encoding: chunked
HTTP/1.1 200 OK
:表示HTTP版本,状态码.
6.1 状态码
HTTP状态码是由三位数字组成的代码,服务器通过这些代码来告知客户端关于HTTP请求的状态。
- 1xx (Informational - 信息性状态码) : 这些状态码表示接收的请求正在处理,通常客户端不需要对它们做出进一步的动作。例如,
100 Continue
表示客户端应继续其请求。 - 2xx (Successful - 成功状态码) : 表示请求已成功被服务器接收、理解,并接受了。最常见的状态码是
200 OK
,表示请求已成功处理。 - 3xx (Redirection - 重定向状态码) : 表示需要客户端采取进一步的操作才能完成请求。例如,
301 Moved Permanently
表示请求的资源已被永久移动到了新的URL。 - 4xx (Client Error - 客户端错误状态码) : 这类状态码指出客户端的请求有误,服务器无法处理。最熟知的例子是
404 Not Found
,意味着请求的资源未找到。 - 5xx (Server Error - 服务器错误状态码) : 表示服务器在处理请求时发生错误。例如,
500 Internal Server Error
指服务器遇到了未知错误,无法完成请求。
状态码有很多,熟悉常见的即可:
状态码 | 含义 |
---|---|
200 (OK) | 成功 |
301 永久重定向 | 请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。 |
302 临时重定向 | 与301类似。但资源只是临时被移动。客户端应继续使用原有URI |
403 阻止访问 | 客户端已知但没有访问权限 |
404 Not Found | 未找到请求的资源 |
405 方法不被允许 | 不支持使用的请求方法,例如,表单需要使用 POST 但使用 GET 代替。 |
500 内部服务器错误 | 服务器遇到某种问题、并且没有更好或更具体的错误代码 |
504 网关超时 | 服务器处于请求中间状态。但是没有收到来自它路由到的服务器的及时响应 |
7.HTTP位于应用层(基于TCP)
HTTP(超文本传输协议)位于TCP/IP模型的应用层。这意味着它是建立在传输层协议之上,特别是基于TCP(传输控制协议)来实现数据的传输。TCP是一种面向连接的、可靠的传输协议,它保证了数据包的顺序传输和错误校验,确保数据的完整性。HTTP利用TCP提供的这些特性来确保从Web服务器到客户端(如浏览器)的请求和响应能够准确无误地传达。
当一个HTTP请求从客户端发出时,首先会通过TCP建立一个从客户端到服务器的连接(这通常涉及到TCP的三次握手过程)。接着,HTTP请求消息通过这个TCP连接发送到服务器,服务器处理请求后,再通过同一个TCP连接将HTTP响应消息返回给客户端。一旦数据交换完成,TCP连接可以被断开.
8.非持久和持久连接
HTTP协议中的非持久连接(Nonpersistent Connections)和持久连接(Persistent Connections)主要区别在于它们管理TCP连接的方式以及如何处理连续的请求和响应。
8.1 非持久连接
在HTTP的早期版本中,如HTTP/1.0,默认使用非持久连接。在这种模式下:
- 每个HTTP请求/响应事务都使用一个新的TCP连接。
- 服务器发送完响应后立即关闭TCP连接,不保留任何状态。
- 如果客户端需要请求多个资源(如图片、CSS文件等),每一个都需要独立建立和关闭TCP连接,这导致了较高的延迟,因为每次连接都需要进行TCP的三次握手和四次挥手过程。
- 这种方式增加了网络负担,因为每个连接都需要分配系统资源,且每次请求都包含了TCP连接的建立和拆除开销。
8.2 持久连接
随着HTTP协议的发展,特别是在HTTP/1.1中,持久连接成为了默认行为,显著提高了效率:
- 一个TCP连接可以用于发送多个HTTP请求和接收多个响应,而不是每个请求都新建连接。
- 服务器在发送完一个响应后,保持TCP连接的开启状态,允许同一个客户端发送额外的请求。
- 这种模式减少了建立和关闭连接的开销,提高了整体性能,降低了延迟,特别是在请求多个资源的场景下更为明显。
- 持久连接有两种形式:
- 无流水线(Non-pipelined)持久连接:客户端需等待前一个请求的响应到达后,才能发送下一个请求。每个对象传输大约需要1个RTT(往返时间)。
- 流水线(Pipelining)持久连接:理论上允许客户端在收到前一个响应之前发送多个请求,这样可以进一步减少延迟,但在实践中由于存在一些问题(如头部阻塞)并未广泛使用。
HTTP协议版本:
- HTTP/1.0:较早的版本,每次请求响应都会建立新的TCP连接。
- HTTP/1.1 :引入了持久连接
(Keep-Alive)
,提高了效率,支持管道化处理请求。 - HTTP/2:进一步优化性能,支持多路复用、二进制分帧、头部压缩等特性。
- HTTP/3:基于QUIC传输协议,改善了延迟和安全性,特别是在高延迟或不可靠的网络环境中。