1. GET 和 POST 请求的区别
GET:幂等且安全
- 目的:用于从服务器获取数据。
- 参数:附加在 URL 中,参数可暴露,数据长度受限(URL 长度限制)。
- 影响:不会更改服务器上的数据。
- 性能:更快,数据嵌入 URL 中,适用于查询操作,对浏览器缓存友好。
POST:非幂等且不安全
- 目的:用于向服务器发送数据,通常会更改服务器上的数据(如表单提交)。
- 参数:通过 HTTP 请求体传输,更隐蔽,没有数据长度限制。
- 性能:相对 GET 较慢,涉及数据的传输,不会被浏览器缓存。
[!TIP] 安全性误区纠正:POST 并不比 GET 更安全。 真相:在网络传输中,GET 和 POST 都是明文传输。如果不使用 HTTPS,黑客抓包都能看得一清二楚。 所谓的“安全”:仅仅是因为 GET 的参数会留在浏览器历史记录、服务器日志里,容易被旁边的人看到,而 POST 的数据在 Body 里,相对隐蔽一点点。
2. 队头阻塞(Head-of-Line Blocking)深度解析
这是两个容易混淆但本质不同的概念:前者属于 应用层 问题,后者属于 传输层 问题。
1) HTTP 层的队头阻塞 (HTTP HOL Blocking)
发生场景:HTTP/1.1 的连接复用或管道化。
- HTTP/1.1 虽然支持持久连接,但同一条连接内的请求必须按照顺序返回。
- 例如:请求 1 → 请求 2 → 请求 3;必须按顺序返回响应 1 → 响应 2 → 响应 3。
- 如果响应 1 很慢,后续请求即使准备好也必须等待,这就是 HTTP 层的队头阻塞。
特点:
- 属于应用层(HTTP)问题。
- 响应必须保持顺序,慢响应会阻塞所有后续请求。
- 浏览器尝试通过限制同域连接数(通常为 6 个)来缓解。
- HTTP/2 通过多路复用从根本上解决了此问题。
2) TCP 层的队头阻塞 (TCP HOL Blocking)
发生场景:TCP 的按序交付机制遇到丢包。
- TCP 保证可靠、有序。只要前面的数据包丢失,接收端必须等待重传。
- 例如:包 #1 丢失,包 #2~#10 虽然已到达也不能交付。
- 所有后续包都被阻塞,这就是 TCP 层的队头阻塞。
特点:
- 属于传输层(TCP)问题。
- 由 TCP 的物理特性(可靠、有序、字节流)引起。
- HTTP/2 仍然基于 TCP,因此依然存在 TCP 层的队头阻塞。
- 只有升级到基于 UDP 的 HTTP/3 (QUIC) 才能解决。
两者的本质区别
| 对比项 | HTTP 层队头阻塞 | TCP 层队头阻塞 |
|---|---|---|
| 所属层 | 应用层 (HTTP) | 传输层 (TCP) |
| 产生原因 | HTTP/1.1 的串行响应顺序 | TCP 的按序交付机制 |
| 表现 | 一个慢响应拖慢整个连接 | 一个丢包拖住整个连接传输 |
| HTTP/2 是否解决 | 是(通过多路复用解决) | 否(仍依赖 TCP) |
| HTTP/3 是否解决 | 是(基于 QUIC/UDP) | 是(按流独立传输) |
为什么 HTTP/3 能彻底解决?
HTTP/3 使用的 QUIC 基于 UDP,不要求数据流全局按序,而是按“流”(Stream)独立处理。某个流丢包不会影响其他流,从而同时解决了应用层和传输层的队头阻塞。
总结
HTTP 层队头阻塞来自 HTTP/1.1 的串行机制;TCP 层队头阻塞来自 TCP 的按序要求。HTTP/2 解决了前者但受困于后者。HTTP/3 通过 QUIC 的流独立机制从根本上解决了这两类问题。
3. HTTP 版本演变
1) HTTP 1.0 vs HTTP 1.1
HTTP 1.1 是目前互联网应用最广泛的版本,主要优化点包括:
- 持久连接 (Persistent Connection):1.1 默认启用
Keep-Alive,允许在同一个 TCP 连接上发送多个 HTTP 请求,大幅减少了 1.0 时代频繁建立连接的时延。 - 断点续传与部分请求:引入了
Range请求头和206 Partial Content状态码,支持只下载资源的一部分。 - 缓存策略升级:不仅保留了 1.0 的
Expires和If-Modified-Since,还新增了性能更好的Cache-Control、Etag和If-None-Match。 - Host 头部支撑:1.1 强制要求请求必须包含
Host字段,使得一台物理服务器(单 IP)可以承载多个虚拟主机。 - 管道网络传输 (Pipelining):支持同时发出多个请求,虽然响应仍需按顺序返回(受限于应用层 HOL 阻塞)。
Host字段: 早期一个 IP 地址只对应一台服务器。后来技术进步了,一个 IP 下可以跑好几个网站(比如 a.com 和 b.com)。如果你不带 Host,服务器就懵了:“你是来找谁的?”所以 1.1 强制要求带上 Host,指名道姓。
2) HTTP 1.1 vs HTTP 2.0
HTTP 2.0 不再追求文本可读性,转而追求机器传输效率。
- 二进制协议 (Binary Framing):头部和数据体都被封装成二进制“帧”。这是实现高效多路复用的底层逻辑。
- 多路复用 (Multiplexing):在单个连接内并行发送多个请求和响应,不再需要按序排队。彻底解决了 HTTP 层的队头阻塞。
- 头部压缩 (Header Compression):通过 HPACK 算法在双端维护映射表,重复传输的头部信息只传“索引号”,极大节省了带宽带宽。
- 服务器推送 (Server Push):服务器可以主动向客户端推送静态资源(如 CSS/JS),无需等客户端解析 HTML 后再发起请求。
头部压缩: 以前每次请求都要反复告诉服务器“我是 Chrome 浏览器”、“我喜欢中文”,这些废话占了一半以上的流量。2.0 在两端各存一张表,以后只发编号(比如:1 代表 Chrome),省下了大量空间。
3) HTTP/3 + UDP (QUIC)
尽管 HTTP 2.0 解决了应用层阻塞,但由于它仍跑在 TCP 之上,TCP 层的队头阻塞依然无法弥补。
HTTP/3 的核心突破点:
- 基于 UDP 的 QUIC 协议:QUIC 在 UDP 之上自研了一套可靠机制。它让多个流在传输层就是独立的,某个流丢包只影响自己,其他流照常传输。
- 极速连接 (0-RTT/1-RTT):将传统的 TCP 握手与 TLS 握手合并,大幅减少了连接建立的往返次数。
- 连接迁移:QUIC 使用随机生成的 Connection ID 识别连接,而非 IP+Port。即使设备切网(如 WiFi 变 4G),连接依然可以维持,不需重连。
版本关键对比表:
| 维度 | HTTP/1.x | HTTP/2 | HTTP/3 |
|---|---|---|---|
| 传输层协议 | TCP | TCP | UDP (QUIC) |
| 连接机制 | 持久连接 (1.1) | 连接复用 | 0-RTT/1-RTT 握手 |
| HOL 阻塞 | 应用层/传输层均存在 | 仅存在传输层 | 彻底消除 |
| 数据格式 | 文本 (ASCII) | 二进制帧 | 二进制帧 |
| 头部压缩 | 无 | HPACK | QPACK |
总结
- HTTP/1.1:主要通过持久连接解决了频繁重连问题。
- HTTP/2:通过多路复用解决了应用层队头阻塞。
- HTTP/3:通过UDP + QUIC彻底解决了因 TCP 丢包重传导致的传输层队头阻塞。
| 协议 | 角色 | 特点 | 缺点 |
|---|---|---|---|
| TCP | 靠谱的老司机 | 必须握手、按序交付、丢包必等 | 慢、有队头阻塞 |
| UDP | 狂奔的送餐员 | 不握手、不保证顺序、丢包不管 | 不可靠(容易丢数据) |
| QUIC | 全能的特种兵 | 基于 UDP,但自己实现了可靠性和加密 | 实现复杂,对路由器要求高 |
4. HTTPS 和 HTTP 的区别,HTTPS 是如何保证安全的
HTTP (HyperText Transfer Protocol)
- 明文传输:数据不加密,内容以纯文本形式在网络中流动。
- 安全性低:容易受到“中间人攻击”(窃听、篡改或嗅探)。
HTTPS (HTTP Secure)
- 数据加密:通过 SSL/TLS 协议(通常基于对称加密与非对称加密结合)对传输内容进行加密。
- 身份验证:利用 CA 证书 验证服务器身份,防止用户访问“钓鱼网站”。
- 完整性校验:通过哈希算法(如 SHA-256)生成数据摘要,确保数据在传输过程中未被篡改。
5. HTTP 状态码速查表
| 状态码类别 | 含义 | 核心作用与常见示例 |
|---|---|---|
| 1xx | 信息性状态码 | 表示请求已被接收,需继续处理。例:100 Continue |
| 2xx | 成功状态码 | 表示请求已正常处理完毕。例:200 OK (成功), 201 Created (创建成功) |
| 3xx | 重定向状态码 | 表示请求需要进一步操作。例:301 Moved Permanently (永久重定向), 302 Found (临时重定向) |
| 4xx | 客户端错误 | 表示请求有误,通常由客户端导致。例:400 Bad Request, 403 Forbidden (无权限), 404 Not Found (资源不存在) |
| 5xx | 服务器错误 | 表示服务器内部故障。例:500 Internal Error, 502 Bad Gateway (网关错误), 503 Service Unavailable |
6. 常见的HTTP请求方法
- GET:用于请求获取资源。
- POST:用于提交数据,通常用于创建或修改资源。
- PUT:用于更新资源。
- DELETE:用于删除资源。
- HEAD:类似于GET,但只请求头部。
- OPTIONS:用于获取支持的请求方法或查询服务器支持的选项。
- PATCH:用于部分更新资源。
7. 浏览器输入 URL 后发生了什么
- DNS解析:浏览器会先解析URL中的域名,获得服务器的IP地址。
- TCP连接:通过三次握手(如果是HTTPS,还会进行SSL/TLS握手)建立TCP连接。
- 发送请求:浏览器根据请求方法(GET、POST等)将数据发送到服务器。
- 服务器响应:服务器处理请求,返回状态码和响应数据。
- 渲染页面:浏览器根据响应的HTML、CSS、JS等文件进行页面渲染。
避坑点: 遇到
<script>标签会发生什么?会阻塞解析!因为 JS 可能会改 DOM,所以浏览器得停下来等 JS 执行完。
- 关闭连接:TCP连接通过四次挥手被关闭。
首先是网络层的 DNS 寻址;拿到 IP 后进入 传输层,通过 TCP 三次握手和 TLS 握手建立安全通道;接着进入 应用层 发起 HTTP 请求;服务器响应后,浏览器内核 开始解析渲染。在解析 HTML 过程中,遇到 CSS 会异步加载,遇到 JS 会阻塞解析。最终经过布局和绘制,把页面呈现给用户。
8. 跨域与同源策略
- 同源策略:浏览器为保证安全性,规定不同域之间的网页不能互相访问。只有在协议、域名、端口都相同的情况下,才能进行交互。
- 跨域问题:当一个网页试图访问另一个域的资源时,就会遇到跨域问题。
常见的跨域解决方法
- CORS(跨源资源共享):通过设置服务器的
Access-Control-Allow-Origin头部,允许特定域的访问。 - JSONP:通过
<script>标签绕过浏览器的同源策略,通常用于 GET 请求。 - WebSocket:通过 WebSocket 协议进行跨域通信。
- 代理:通过设置代理服务器来绕过同源策略。
9. 与缓存相关的 HTTP 请求(响应)头有哪些
强缓存
- Expires(HTTP 1.0):指定一个日期,浏览器在此日期之前不会向服务器发送请求。
- Cache-Control(HTTP 1.1):设置缓存的策略,如
no-store(不缓存)、max-age(最大缓存时间)等。
协商缓存
- ETag:是资源的唯一标识符,服务器通过返回 ETag 值判断资源是否发生变化。
- If-None-Match:客户端在请求时携带 ETag,服务器判断是否存在差异,如果没有则返回
304 Not Modified。 - Last-Modified:指定资源的最后修改时间。
- If-Modified-Since:客户端在请求时携带 Last-Modified,服务器判断资源是否已被修改,如果未修改返回
304。