Linux笔记---HTTP协议

1. 什么是HTTP协议

HTTP(HyperText Transfer Protocol,超文本传输协议) 是互联网中最基础、最核心的应用层协议 ,用于在客户端(如浏览器)服务器 之间传输超文本(如 HTML、图片、视频、API 数据等)。它基于TCP/IP 协议栈 工作,定义了请求与响应的格式、交互流程及资源访问规则,是万维网(WWW)得以运行的基石。

HTTP协议是如何在万维网中发挥作用的呢?举个例子,我们在使用浏览器访问网页的时候,浏览器 就会根据你提供的网址向特定的服务器发送一个HTTP请求报文服务器 收到请求报文之后会解析该报文,分析浏览器想要请求什么网页资源,并将该资源封装为响应报文并发送回去

1.1 HTTP协议的核心特征

HTTP 的设计围绕 "简单、灵活、可扩展" 展开,核心特性包括:

  • 应用层协议
    HTTP 工作在 OSI 模型的应用层,依赖传输层的 TCP 协议提供可靠的字节流传输(HTTP/3 除外,基于 UDP 的 QUIC 协议),无需关心底层网络(如 IP 路由、数据链路)的细节。
  • 无状态(Stateless)
    HTTP 本身是 "无状态" 的 ------服务器不会保留客户端的历史请求信息。例如,用户第一次登录后,第二次请求时服务器无法直接识别该用户,需通过Cookie、Session或 Token(如 JWT)等机制 "补充状态"。 优点:简化服务器设计,降低内存开销,支持高并发; 缺点:需额外机制维护会话,增加开发复杂度。
  • 请求 - 响应模型(Request-Response)
    严格遵循 "客户端主动请求,服务器被动响应" 的交互模式: 客户端(如 Chrome)发起请求(如访问https://www.baidu.com); 服务器接收请求并处理(如查询数据库、生成 HTML); 服务器返回响应(如 HTML 页面或错误信息); 一次交互完成(连接可保留或关闭)。
  • 可扩展(Extensible)
    HTTP 通过头部字段(Header) 实现灵活扩展:用户可自定义头部(如X-Requested-With: XMLHttpRequest标识 AJAX 请求),或基于标准扩展功能(如Cache-Control控制缓存、Accept-Encoding支持压缩)。
  • 媒体无关性
    HTTP 不限制传输的数据类型,通过Content-Type头部(如text/html、image/jpeg、application/json)标识资源格式,可传输文本、图片、视频、二进制文件等任意媒体。

1.2 HTTP 的工作流程(基于 TCP)

HTTP 的经典交互流程基于 TCP 的 "三次握手" 建立连接、"四次挥手" 关闭连接,具体步骤如下(以 HTTP/1.1 为例):

  1. 建立 TCP 连接(三次握手)
    客户端向服务器的目标端口(默认 HTTP 为 80,HTTPS 为 443)发送 SYN 报文,服务器返回 SYN+ACK,客户端再返回 ACK,最终建立可靠的 TCP 连接。
  2. 客户端发送 HTTP 请求
    连接建立后,客户端向服务器发送结构化的 HTTP 请求报文(包含请求行、请求头、请求体)。
  3. 服务器处理并返回响应
    服务器解析请求(如识别请求方法、资源路径),执行业务逻辑(如查询数据库、生成页面),然后向客户端返回 HTTP 响应报文(包含状态行、响应头、响应体)。
  4. 关闭 TCP 连接(四次挥手)
    若为短连接(HTTP/1.0 默认):响应后立即关闭 TCP 连接,下次请求需重新建立连接; 若为长连接(HTTP/1.1 默认,通过Connection: Keep-Alive启用):连接可保留一段时间(如 30 秒),后续请求可复用该连接,减少握手开销。
  5. 客户端解析响应
    客户端(如浏览器)解析响应内容:若为 HTML 则渲染页面,若为 JSON 则处理数据,若为错误状态码则提示用户(如 404 "页面不存在")。

2. URL

**URL(Uniform Resource Locator,统一资源定位符)**是互联网中用于定位资源(如网页、图片、文件、API 接口等)的标准地址格式。它的核心作用是告诉浏览器或客户端 "去哪里" 获取指定资源,相当于网络世界中资源的 "门牌地址"。

我们所说的网址,实际上就是URL。

2.1 URL结构

|---------------------|----------------------|-----------------------------------------------------------|---------------------------------------------------------------|
| 组成部分 | 符号标识 | 含义与作用 | 备注 |
| 协议(Scheme) | 开头至**://** | 指定访问资源的网络协议。 | 常见协议:http(超文本传输)、https(加密传输)、ftp(文件传输)、mailto(邮件)等。 |
| 用户信息(User Info) | :// 后至**@** | 可选,用于身份验证(如 FTP 登录),格式为 "用户名:密码"。 | 因安全性问题,HTTP/HTTPS 中几乎不再使用(明文传输密码风险高),仅 FTP 等场景偶尔使用。 |
| 域名(Host) | @ 后至**:** 或**/** | 资源所在服务器的网络地址(可是域名或 IP 地址)。 | 域名可细分:com(顶级域名)、example(二级域名)、www(子域名);也可直接用 IP,如192.168.1.1。 |
| 端口(Port) | : 后至**/** | 可选,指定服务器上的 "应用端口"。 | 协议默认端口可省略:HTTP 默认 80,HTTPS 默认 443,FTP 默认 21。若端口非默认,必须显式写出。 |
| 路径(Path) | / 后至**?** 或**#** | 资源在服务器上的 "文件路径",定位服务器内具体的资源位置。网页的根目录与操作系统无关,由服务器自己定义。 | 类似本地文件系统的路径(如C:/Users/Documents),用/分隔层级。 |
| 查询参数(Query) | ? 后至**#** | 可选,向服务器传递 "动态参数",格式为 "键值对"(Key=Value),多参数用&分隔。 | 常用于动态页面(如搜索结果、分页),服务器可根据参数返回不同内容(如?page=2表示第 2 页)。 |
| 片段标识符(Fragment) | **#**后至结尾 | 可选,定位 "资源内部的片段"(仅客户端解析,不发送给服务器)。 | 常用于网页内锚点跳转(如跳转到页面的 "第 1 节"),服务器接收请求时会忽略该部分。 |

2.2 URL编码

URL 的语法规则限制:仅允许包含字母(a-z/A-Z)、数字(0-9)和部分特殊字符(如-、_、.、/、?等) 。若 URL 中包含空格、中文、特殊符号(如&、#、@),会导致客户端解析错误或服务器无法识别,因此需要通过 "编码" 将这些字符转换为合法格式。

编码规则

  • 核心逻辑 :将非法字符转换为 "% + 该字符的 ASCII 码(或 UTF-8 编码)的十六进制表示"。

  • 常见编码示例

    |---------|--------------------|-----------------------------------------------------|
    | 原始字符 | 编码后结果 | 说明 |
    | 空格 | %20 | 空格的 ASCII 码为 32(十六进制为 20) |
    | 中文 "测试" | %E6%B5%8B%E8%AF%95 | 中文采用 UTF-8 编码,"测" 的 UTF-8 十六进制为 E6B58B,"试" 为 E8AF95 |
    | & | %26 | &是查询参数的分隔符,若作为普通字符需编码 |
    | # | %23 | #是片段标识符的开头,普通使用需编码 |

  • 实际场景:当你在百度搜索 "URL 编码" 时,浏览器会自动将中文编码为: https://www.baidu.com/s?wd=URL 编码

3. HTTP报文结构

3.1 请求报文

|----------|-----------------------------------------------------------------|
| 组成部分 | 说明 |
| 请求行 | [请求方法 + 空格 + 请求 URL + 空格 + HTTP 版本 + 换行符] |
| 请求头部 | [Key + 冒号 + 空格 + Value + 换行符],描述客户端信息、请求偏好等,可以有若干行,根据需要提供 |
| 空行 | 不含任何内容的一行,即只有一个换行符,用于标志报头的结束 |
| 请求体 | 可选,用于提交数据(如 POST 请求的表单数据、JSON 数据) |

例如,使用浏览器访问我们的服务器端,我们就会收到如下的消息(请求报文):

bash 复制代码
[2025-09-12 10:10:36] [INFO] [69067] [Http.hpp] [208] - 来自[113.54.241.175:55388]的Http请求报文:
GET /favicon.ico HTTP/1.1
Host: 110.41.32.137:8888
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36
Accept: image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
Referer: http://110.41.32.137:8888/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9

3.2 响应报文

|----------|-----------------------------------------------------------------|
| 组成部分 | 说明 |
| 状态行 | [HTTP 版本 + 空格 + 状态码 + 空格 + 状态码描述 + 换行符] |
| 响应头部 | [Key + 冒号 + 空格 + Value + 换行符],描述服务器信息、响应属性等,可以有若干行,根据需要提供 |
| 空行 | 不含任何内容的一行,即只有一个换行符,用于标志报头的结束 |
| 响应体 | 可选,包含请求的资源(如 HTML 页面、图片二进制数据、API JSON 结果) |

例如,我们使用telnet命令访问www.baidu.com,并请求它的主页,我们就会收到如下响应报文:

bash 复制代码
shishen@hcss-ecs-b8e6:~/113code/linux-c/Http协议$ telnet www.baidu.com 80
Trying 183.2.172.177...
Connected to www.a.shifen.com.
Escape character is '^]'.
GET / HTTP/1.1

HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 29506
Content-Type: text/html
Date: Fri, 12 Sep 2025 03:00:26 GMT
P3p: CP=" OTI DSP COR IVA OUR IND COM "
P3p: CP=" OTI DSP COR IVA OUR IND COM "
Pragma: no-cache
Server: BWS/1.1
Set-Cookie: BAIDUID=DBD78364274658CE3DF78A347B084092:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BIDUPSID=DBD78364274658CE3DF78A347B084092; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: PSTM=1757646026; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BAIDUID=DBD78364274658CEBA3DF64A117E4633:FG=1; max-age=31536000; expires=Sat, 12-Sep-26 03:00:26 GMT; domain=.baidu.com; path=/; version=1; comment=bd
Tr_id: pr_0xeaf4371901c48577
Traceid: 1757646026127905485810851600136077958114
Vary: Accept-Encoding
X-Ua-Compatible: IE=Edge,chrome=1
X-Xss-Protection: 1;mode=block

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta content="always" name="referrer" />
    <meta
        name="description"
        content="全球领先的中文搜索引擎、致力于让网民更便捷地获取信息,找到所求。百度超过千亿的中文网页数据库,可以瞬间找到相关的搜索结果。"
    />
    <link rel="shortcut icon" href="//www.baidu.com/favicon.ico" type="image/x-icon" />

下面的部分省略............

4. HTTP报文核心属性

4.1 HTTP请求方法

**请求方法(Method)**用于指定客户端对服务器资源的操作意图,HTTP/1.1 定义了 8 种标准方法,核心方法及特性如下:

|-------------|-------------------------|----------|-----------|-------------|
| 方法 | 核心用途 | 是否幂等 | 是否可缓存 | 是否有请求体 |
| GET | 获取服务器资源(如访问页面、查询数据) | 是 | 是 | 否(数据拼在 URL) |
| POST | 向服务器提交数据(如表单提交、上传文件) | 否 | 否 | 是 |
| PUT | 全量更新资源(如替换用户信息) | 是 | 否 | 是 |
| DELETE | 删除资源(如删除一篇文章) | 是 | 否 | 否 |
| PATCH | 部分更新资源(如仅修改用户昵称) | 是 | 否 | 是 |
| HEAD | 仅获取响应头部(无响应体),用于检查资源 | 是 | 是 | 否 |
| OPTIONS | 询问服务器支持的方法(如 CORS 预检请求) | 是 | 否 | 否 |
| TRACE | 回显请求,用于调试(极少使用,有安全风险) | 是 | 否 | 否 |

注:幂等性指 "多次执行同一请求,结果与执行一次一致"。例如,多次 GET 同一资源结果相同(幂等),多次 POST 提交表单会重复创建数据(非幂等)。

4.2 HTTP状态码

状态码(Status Code)是服务器返回的 3 位数字,用于标识请求的处理状态,分为 5 大类(首数字代表类别):

|---------|-------------|----------------------------------------------------------------------------------------------------------------------------------------------------|
| 类别 | 含义 | 常见状态码及说明 |
| 1xx | 信息型(临时响应) | 100 Continue:服务器已接收请求头,客户端可继续发送请求体(如大文件上传) |
| 2xx | 成功型(请求处理完成) | 200 OK:请求成功(默认) 204 No Content:请求成功,但无响应体(如 DELETE 成功) |
| 3xx | 重定向(需进一步操作) | 301 Moved Permanently:永久重定向(如域名变更) 302 Found:临时重定向(如临时维护) 304 Not Modified:资源未修改,可使用本地缓存(重要优化) |
| 4xx | 客户端错误(请求有误) | 400 Bad Request:请求参数错误 401 Unauthorized:未登录(需身份验证) 403 Forbidden:已登录,但无权限(如访问管理员页面) 404 Not Found:资源不存在(最常见错误) |
| 5xx | 服务器错误(处理失败) | 500 Internal Server Error:服务器未知错误(如代码 Bug) 502 Bad Gateway:网关错误(如服务器宕机) 503 Service Unavailable:服务器过载或维护(临时不可用) 504 Gateway Timeout:网关超时(如服务器处理过慢) |

4.3 HTTP头部字段

头部字段(Header)用于配置HTTP报文的可选属性,按用途可分为 4 类:

4.3.1 通用头部(General Headers)

客户端和服务器 均可使用,描述整体请求 / 响应的属性

  • Date:报文生成时间(如 Date: Tue, 12 Sep 2025 12:00:00 GMT);
  • Cache-Control:缓存控制策略(如 Cache-Control: max-age=3600 表示缓存 1 小时);
  • Connection:连接状态(如 Connection: Keep-Alive 启用长连接,Connection: close 关闭连接);
  • Transfer-Encoding:数据传输编码(如 Transfer-Encoding: chunked 分块传输,用于未知长度的响应体)。
4.3.2 请求头部(Request Headers)

客户端 发送,描述客户端信息或请求偏好

  • Host:目标服务器域名 + 端口(HTTP/1.1 必需,支持虚拟主机,如 Host: www.baidu.com:80);
  • User-Agent(UA):客户端标识(如浏览器版本、设备信息,如 Mozilla/5.0 (iPhone; ...) Safari/537.36);
  • Accept:客户端可接收的媒体类型(如 Accept: application/json, text/plain); Accept-
  • Encoding:客户端支持的压缩格式(如 Accept-Encoding: gzip, deflate,服务器用 gzip 压缩响应体以节省带宽);
  • Authorization:身份验证信息。
4.3.3 响应头部(Response Headers)

服务器 发送,描述服务器信息或响应属性

  • Server:服务器软件标识(如 Server: Apache/2.4.49 或 Server: nginx);
  • Set-Cookie:向客户端设置 Cookie(如 Set-Cookie: sessionid=abc123; Path=/; HttpOnly,用于会话管理);
  • Location:重定向目标地址(配合 3xx 状态码,如 Location: https://new.baidu.com);
  • Access-Control-Allow-Origin:跨域资源共享(CORS)配置(如 Access-Control-Allow-Origin: * 允许所有域名跨域)。
4.3.4 实体头部(Entity Headers)

描述请求体 / 响应体(data部分)的属性(如类型、长度):

  • Content-Type:实体内容的媒体类型(核心头部,如 Content-Type: text/html; charset=utf-8、
  • Content-Type: image/png、Content-Type: application/json);
  • Content-Length:实体内容的字节长度(如 Content-Length: 1024,服务器需准确计算,否则客户端可能解析错误);
  • Content-Encoding:实体内容的压缩格式(如 Content-Encoding: gzip,对应客户端的 Accept-Encoding)。

5. HTTP版本演进

HTTP 自 1991 年诞生以来,经历了多次版本迭代,核心目标是提升性能、降低延迟、增强功能:

|--------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------|
| 版本 | 发布时间 | 核心改进 | 局限性 |
| HTTP/0.9 | 1991 年 | 首个版本,极简设计: - 仅支持 GET 方法 ; - 仅传输纯文本 (无 HTML 外标签); - 无状态码、头部字段。 | 功能单一,无法传输图片、视频,仅适用于早期纯文本网页。 |
| HTTP/1.0 | 1996 年 | 首次标准化: - 新增 POST、HEAD 方法; - 支持状态码、头部字段; - 支持多种媒体类型(图片、音频); - 引入 Cookie(补充状态)。 | 默认短连接(每次请求新建 TCP 连接),握手开销大; 无管线化(需等待前一个请求响应后再发下一个)。 |
| HTTP/1.1 | 1999 年 | 解决 1.0 性能问题: - 默认长连接(Keep-Alive),复用 TCP 连接; - 支持管线化(并行发送多个请求,无需等待响应); - 支持虚拟主机(Host 头部); - 支持 Chunked 编码(分块传输未知长度数据)。 | 管线化兼容性差(多数服务器不支持); 队头阻塞(同一连接中,前一个请求阻塞后续请求)。 |
| HTTP/2 | 2015 年 | 性能飞跃(基于 SPDY 协议): - 二进制帧 (替代 1.x 的文本格式,解析更快、错误更少); - 多路复用 (同一连接中并行处理多个请求,无队头阻塞); - 头部压缩 (HPACK 算法,减少重复头部传输); - 服务器推送(主动向客户端推送关联资源,如 HTML+CSS)。 | 仍基于 TCP,若 TCP 连接丢失(如网络波动),所有请求需重连; 队头阻塞问题转移到 TCP 层(TCP 重传导致所有帧阻塞)。 |
| HTTP/3 | 2022 年 | 突破 TCP 限制(基于 QUIC 协议): -基于UDP传输(无 TCP 三次握手,连接建立更快); -解决队头阻塞(每个请求独立帧,丢失仅重传单个帧); - 内置 TLS 1.3 加密(无需额外握手); - 支持连接迁移(如手机从 WiFi 切到 5G,无需重新建立连接)。 | 兼容性仍在提升(部分 CDN、服务器未完全支持); UDP 在部分网络环境中可能被限制。 |

相关推荐
2501_915909065 小时前
HTTPS 错误解析,常见 HTTPS 抓包失败、443 端口错误与 iOS 抓包调试全攻略
android·网络协议·ios·小程序·https·uni-app·iphone
lingggggaaaa12 小时前
小迪安全v2023学习笔记(八十一讲)—— 框架安全&ThinkPHP&Laravel&Struts2&SpringBoot&CVE复现
笔记·学习·struts·安全·网络安全·laravel
乖女子@@@14 小时前
协议_https协议
http·https·iphone
ooolmf14 小时前
照度传感器考虑笔记
笔记·单片机
yangzhi_emo15 小时前
ES6笔记5
前端·笔记·es6
Awesome Baron15 小时前
《Learning Langchain》阅读笔记13-Agent(1):Agent Architecture
笔记·langchain·llm
鸡哥爱技术15 小时前
Django入门笔记
笔记·python·django
Katherine_lin15 小时前
UDP特点及报文结构
网络·网络协议·udp
q5673152315 小时前
自动化拨号爬虫体系:虚拟机集群部署与增量管理
运维·爬虫·网络协议·自动化