一、HTTP 请求/响应完整流程(登录案例)
假设用户在登录页面输入:
txt
手机号:13800138000
密码:123456
点击登录按钮。
前端 JavaScript 代码:
js
fetch("/login", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
telephone: "13800138000",
password: "123456"
})
})
浏览器会自动构造 HTTP 请求:
http
POST /login HTTP/1.1
Host: localhost:8000
Content-Type: application/json
{
"telephone":"13800138000",
"password":"123456"
}
后端 Gin 路由:
go
GE.POST("/login", Login)
收到请求后:
go
func Login(c *gin.Context) {
var req LoginReq
c.ShouldBindJSON(&req)
}
Gin 内部流程:
txt
读取 Body
↓
解析 JSON
↓
根据 json 标签匹配字段
↓
填充结构体
↓
执行参数校验
得到:
go
req.Telephone
req.Password
随后:
txt
查询数据库
↓
验证账号密码
↓
生成 JWT
↓
返回结果
返回:
go
c.JSON(200, gin.H{
"token": token,
"msg": "登录成功",
})
响应:
json
{
"token":"xxxxx",
"msg":"登录成功"
}
前端收到响应:
js
const res = await fetch(...)
const data = await res.json()
localStorage.setItem("token", data.token)
至此登录完成。
完整链路:
txt
用户点击登录
↓
前端 fetch
↓
HTTP 请求
↓
Gin 路由
↓
ShouldBindJSON
↓
数据库查询
↓
生成 JWT
↓
c.JSON 返回
↓
前端接收 JSON
↓
保存 Token
↓
页面跳转
二、HTTP 请求由什么组成
一个完整请求:
http
POST /login HTTP/1.1
Host: localhost:8000
Content-Type: application/json
{
"telephone":"13800138000",
"password":"123456"
}
分为四部分。
1. 请求方法(Method)
txt
GET
POST
PUT
DELETE
表示客户端想干什么。
例如:
txt
GET 查询
POST 新增
PUT 修改
DELETE 删除
2. 请求路径(Path)
txt
/login
/user/info
/todo/list
决定执行哪个接口。
例如:
go
r.POST("/login", Login)
请求:
txt
/login
执行:
go
Login()
3. 请求头(Header)
例如:
http
Content-Type: application/json
Authorization: Bearer xxxxx
作用:
txt
说明数据格式
携带 Token
携带 Cookie
携带浏览器信息
4. 请求体(Body)
真正的数据。
json
{
"telephone":"13800138000",
"password":"123456"
}
Gin:
go
c.ShouldBindJSON(&req)
就是读取这里的数据。
三、HTTP 响应由什么组成
后端返回:
http
HTTP/1.1 200 OK
Content-Type: application/json
{
"msg":"success"
}
包含三部分。
1. 状态码
txt
200 成功
400 参数错误
401 未登录
403 无权限
404 找不到资源
500 服务器异常
2. 响应头
http
Content-Type: application/json
告诉浏览器:
txt
返回的是 JSON 数据
3. 响应体
json
{
"msg":"success"
}
真正返回的数据。
四、TCP 三次握手
HTTP 请求发送之前。
必须先建立 TCP 连接。
第一次握手
客户端发送:
txt
SYN
意思:
txt
我要建立连接
第二次握手
服务器回复:
txt
SYN + ACK
意思:
txt
我收到了
我也准备好了
第三次握手
客户端回复:
txt
ACK
意思:
txt
收到
开始通信
过程:
txt
客户端 服务器
SYN ------------------>
<-------------- SYN + ACK
ACK ------------------>
连接建立成功。
为什么必须三次?
目的:
txt
客户端确认:
服务器能收
服务器能发
服务器确认:
客户端能收
客户端能发
三次刚好。
两次不够。
四次浪费。
五、TCP 四次挥手
关闭连接时:
第一次挥手
客户端:
txt
FIN
意思:
txt
我没数据发了
第二次挥手
服务器:
txt
ACK
意思:
txt
收到
但我还有数据没发完
第三次挥手
服务器:
txt
FIN
意思:
txt
我也发完了
第四次挥手
客户端:
txt
ACK
意思:
txt
收到
连接关闭
过程:
txt
客户端 服务器
FIN ------------------>
<-------------- ACK
<-------------- FIN
ACK ------------------>
六、TCP 和 UDP 的区别
TCP
特点:
txt
面向连接
可靠传输
保证顺序
保证不丢包
应用:
txt
HTTP
HTTPS
MySQL
Redis
WebSocket
UDP
特点:
txt
无连接
不保证到达
不保证顺序
速度快
应用:
txt
视频直播
语音通话
在线游戏
实时音视频
对比:
| 特性 | TCP | UDP |
|---|---|---|
| 是否连接 | 需要 | 不需要 |
| 是否可靠 | 是 | 否 |
| 是否有序 | 是 | 否 |
| 速度 | 较慢 | 较快 |
| 应用 | HTTP、数据库 | 直播、游戏 |
七、HTTP、TCP、IP 三者关系
很多人学到这里容易混。
实际上:
txt
HTTP
↓
TCP
↓
IP
HTTP
负责:
txt
规定数据格式
例如:
http
POST /login HTTP/1.1
属于 HTTP 协议。
TCP
负责:
txt
可靠传输数据
保证:
txt
不丢包
不重复
不乱序
IP
负责:
txt
找到目标机器
例如:
txt
192.168.1.100
8.8.8.8
这些都是 IP 地址。
快递类比
txt
HTTP = 信件内容格式
TCP = 快递运输规则
IP = 收件地址
八、真实项目中的完整链路
以 Gin 项目为例:
txt
用户
↓
Vue 页面
↓
Axios / Fetch
↓
HTTP 请求
↓
TCP 三次握手
↓
Gin 路由
↓
ShouldBindJSON
↓
Service 业务层
↓
GORM
↓
MySQL
↓
返回 JSON
↓
前端渲染页面
九、一句话总结
前端负责页面,后端负责数据。
用户点击按钮后,前端通过 HTTP 发送 JSON 数据,HTTP 底层通过 TCP 三次握手建立连接,再通过 IP 找到服务器。Gin 接收请求后解析 JSON、处理业务并返回响应,前端收到 JSON 后更新页面,这样就完成了一次完整的前后端通信。
txt
前端
↓
HTTP
↓
TCP
↓
Gin
↓
MySQL
↓
Gin
↓
HTTP
↓
前端