引言
HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上最基础、最广泛使用的应用层协议。你在浏览器中输入网址、点击链接、提交表单——背后都是 HTTP 在传输数据。
然而,很多开发者对 HTTP 的理解停留在"请求-响应"四个字。一旦被问到"HTTP 报文长什么样?请求头有哪些?状态码 301 和 302 有什么区别?POST 和 GET 到底哪里不同?"就答不上来。
本文作为 HTTP 系列第一篇,将彻底讲透 HTTP 最基础、也最核心的内容:报文结构、状态码、请求头和响应头。这是后续理解缓存、Cookie、HTTPS、跨域等高级特性的基石。
第一部分:HTTP 基础回顾
一、什么是 HTTP
HTTP 是客户端(浏览器)和服务器之间请求-响应式的通信协议。
二、HTTP 的核心特点
| 特点 | 说明 |
|---|---|
| 无状态 | 每次请求都是独立的,服务器不记得上次是谁、做了什么 |
| 基于 TCP | 可靠传输,默认端口 80 |
| 请求-响应 | 客户端主动,服务器被动 |
| 可扩展 | 通过请求头/响应头灵活扩展功能 |
第二部分:HTTP 请求报文
一、请求报文结构
一个真实的 GET 请求报文(用curl -v抓取):
GET /api/users HTTP/1.1 Host: www.example.com User-Agent: curl/7.68.0 Accept: */* Connection: keep-alive一个真实的 POST 请求报文:
POST /api/login HTTP/1.1 Host: www.example.com Content-Type: application/x-www-form-urlencoded Content-Length: 27 User-Agent: Mozilla/5.0 Connection: keep-alive username=admin&password=123二、请求行(Request Line)
格式:方法 URL 协议版本
| 组成部分 | 说明 | 示例 |
|---|---|---|
| 方法 | 对资源的操作 | GET、POST、PUT、DELETE |
| URL | 请求的资源路径 | /index.html、/api/users |
| 协议版本 | HTTP 版本号 | HTTP/1.1、HTTP/2 |
三、常见请求方法
| 方法 | 含义 | 请求体 | 幂等性 | 安全性 |
|---|---|---|---|---|
| GET | 获取资源 | ❌ 无 | ✅ | ✅ 安全 |
| POST | 提交数据/创建资源 | ✅ 有 | ❌ | ❌ 不安全 |
| PUT | 更新资源(全量替换) | ✅ 有 | ✅ | ❌ |
| PATCH | 更新资源(部分修改) | ✅ 有 | ❌ | ❌ |
| DELETE | 删除资源 | ❌ 通常无 | ✅ | ❌ |
| HEAD | 只获取响应头(无体) | ❌ 无 | ✅ | ✅ |
| OPTIONS | 查询服务器支持的方法 | ❌ 无 | ✅ | ✅ |
| TRACE | 回显请求(调试用) | ❌ 无 | ✅ | ✅ |
| CONNECT | 建立隧道(HTTPS 代理) | — | — | — |
幂等性:多次相同的请求,结果一样。GET(查询)、PUT(全量更新)、DELETE(删除)是幂等的;POST(新增)不是——两次 POST 会创建两条记录。
安全性:不修改服务器数据的方法叫"安全"方法。GET 是安全的,POST/PUT/DELETE 不是。
GET 和 POST 的区别(面试必问)
| 对比项 | GET | POST |
|---|---|---|
| 语义 | 获取资源 | 提交数据/创建资源 |
| 参数位置 | URL 查询字符串 | 请求体 |
| 参数长度 | 受 URL 长度限制(浏览器限制约 2KB) | 无限制 |
| 缓存 | 可缓存 | 默认不缓存 |
| 书签 | 可以收藏 | 不能 |
| 后退/刷新 | 无害 | 会提示重新提交 |
| 幂等性 | ✅ 幂等 | ❌ 不幂等 |
| 安全性 | ✅ 安全 | ❌ 不安全 |
| 可见性 | URL 中可见 | 请求体中,相对隐蔽 |
四、常见请求头
| 请求头 | 含义 | 示例 |
|---|---|---|
Host | 请求的主机名(必选,HTTP/1.1) | Host: www.example.com |
User-Agent | 客户端信息(浏览器/系统) | User-Agent: Mozilla/5.0... |
Accept | 客户端能接受的 MIME 类型 | Accept: text/html, */* |
Accept-Encoding | 客户端能接受的压缩方式 | Accept-Encoding: gzip, deflate |
Accept-Language | 客户端期望的语言 | Accept-Language: zh-CN, zh |
Connection | 连接管理 | Connection: keep-alive |
Content-Type | 请求体的 MIME 类型 | Content-Type: application/json |
Content-Length | 请求体的字节数 | Content-Length: 128 |
Cookie | 携带的 Cookie | Cookie: session_id=abc123 |
Referer | 来源页面 URL | Referer: https://www.baidu.com |
Authorization | 认证信息 | Authorization: Bearer token123 |
Cache-Control | 缓存控制 | Cache-Control: no-cache |
Origin | 请求来源(跨域相关) | Origin: https://www.example.com |
Content-Type 详解
第三部分:HTTP 响应报文
一、响应报文结构
一个真实的响应报文:
HTTP/1.1 200 OK Server: nginx/1.18.0 Date: Mon, 02 Jun 2024 10:00:00 GMT Content-Type: text/html; charset=utf-8 Content-Length: 127 Connection: keep-alive Cache-Control: max-age=3600 <!DOCTYPE html> <html> <head><title>Example</title></head> <body>Hello World</body> </html>二、状态行(Status Line)
格式:协议版本 状态码 状态描述
三、状态码全解
301 vs 302
401 vs 403
| 状态码 | 含义 | 典型场景 |
|---|---|---|
| 401 Unauthorized | 需要登录 | 未登录访问需要权限的页面 |
| 403 Forbidden | 登录了但权限不够 | 普通用户访问管理员页面 |
四、常见响应头
| 响应头 | 含义 | 示例 |
|---|---|---|
Content-Type | 响应体的 MIME 类型和编码 | Content-Type: text/html; charset=utf-8 |
Content-Length | 响应体的字节数 | Content-Length: 1024 |
Server | 服务器软件信息 | Server: nginx/1.18.0 |
Date | 响应生成时间(GMT) | Date: Mon, 02 Jun 2024 10:00:00 GMT |
Set-Cookie | 设置 Cookie | Set-Cookie: session=abc123; HttpOnly |
Cache-Control | 缓存控制 | Cache-Control: max-age=3600 |
Location | 重定向地址 | Location: https://www.new-url.com |
Access-Control-Allow-Origin | 跨域允许的来源 | Access-Control-Allow-Origin: * |
Content-Encoding | 内容压缩方式 | Content-Encoding: gzip |
第四部分:Connection 与长短连接
一、短连接与长连接
请求头:Connection: keep-alive → 请求保持连接
响应头:Connection: keep-alive → 服务器同意保持连接
响应头:Connection: close → 服务器要关闭连接
第五部分:MIME 类型
服务器通过Content-Type告诉浏览器"返回的是什么",浏览器据此决定如何处理(渲染 HTML、显示图片、下载文件等)。
第六部分:用 curl 抓取完整报文
# 抓取完整请求和响应(包括头部) curl -v https://www.example.com # 输出示例: # > GET / HTTP/1.1 ← 请求行(> 表示发出的数据) # > Host: www.example.com ← 请求头 # > User-Agent: curl/7.68.0 # > Accept: */* # > # < HTTP/1.1 200 OK ← 状态行(< 表示收到的数据) # < Content-Type: text/html ← 响应头 # < Content-Length: 1256 # < # <html>... ← 响应体第七部分:HTTP 面试题
1. Q:GET 和 POST 的区别?
A:GET 获取资源,参数在 URL 中,可缓存、可收藏、幂等;POST 提交数据,参数在请求体中,不可缓存、不幂等。
2. Q:301 和 302 的区别?
A:301 永久重定向(浏览器会记住新地址,搜索引擎更新索引);302 临时重定向(下次还访问原地址)。
3. Q:401 和 403 的区别?
A:401 表示"没登录,请先登录";403 表示"登录了但没权限访问"。
4. Q:HTTP 是无状态的,怎么记住用户?
A:通过 Cookie(服务器返回 Set-Cookie,浏览器下次请求自动带上)或 Token(JWT 等,存在客户端,每次请求携带)。
5. Q:HTTP/1.0 和 HTTP/1.1 的区别?
A:HTTP/1.1 默认长连接(Connection: keep-alive)、增加了 Host 头(一台服务器托管多个网站)、增加了缓存控制(Cache-Control)、支持管道化。
6. Q:Content-Type 的作用?
A:告诉服务器/浏览器"数据是什么格式"。服务端据此解析请求体,浏览器据此决定如何处理响应体。
7. Q:POST 请求的数据格式有哪些?
A:application/x-www-form-urlencoded(默认表单)、multipart/form-data(上传文件)、application/json(RESTful API 常用)。
总结
一、核心要点
| 主题 | 关键内容 |
|---|---|
| 请求报文 | 请求行 + 请求头 + 空行 + 请求体 |
| 响应报文 | 状态行 + 响应头 + 空行 + 响应体 |
| 请求方法 | GET/POST/PUT/DELETE,幂等和安全 |
| 状态码 | 1xx/2xx/3xx/4xx/5xx,301 vs 302,401 vs 403 |
| 关键头部 | Content-Type、Connection、Cookie、Cache-Control |
| 长连接 | HTTP/1.1 默认,Connection: keep-alive |
二、一句话记忆
HTTP 是请求-响应协议,报文由"行→头→空行→体"四部分组成。GET 获取数据参数在 URL,POST 提交数据参数在体。状态码 2xx 成功、3xx 重定向、4xx 客户端错、5xx 服务器错。HTTP/1.1 默认长连接,Content-Type 决定数据格式。