--- tags: [后端, HTTP, 协议, 基础] create time: 2026-04-24 18:41 --- # HTTP 协议 ## 概述 HTTP(HyperText Transfer Protocol)是浏览器和服务器之间通信的"语言"。理解 HTTP 是理解 Web 工作原理的第一步。 思考题:你在浏览器地址栏输入 `https://www.google.com` 后按下回车,HTTP 协议在这个过程中扮演了什么角色? ## 正文 ### 1. HTTP 请求结构 ``` 请求行 → 方法 + URL + 协议版本 请求头 → Key-Value 对,携带元信息 空行 请求体 → GET 请求通常为空,POST/PUT 有数据 ``` ``` POST /api/users HTTP/1.1 Host: api.example.com Content-Type: application/json Authorization: Bearer eyJhbGciOiJIUzI1NiIs... Content-Length: 42 {"name": "Alice", "age": 25} ``` ### 2. HTTP 方法(动词) | 方法 | 语义 | 幂等性 | 典型场景 | |------|------|--------|----------| | `GET` | 读取数据 | ✅ 是 | 获取列表、详情 | | `POST` | 创建资源 | ❌ 否 | 提交表单、创建用户 | | `PUT` | 全量更新 | ✅ 是 | 完整替换一个资源 | | `PATCH` | 部分更新 | ❌ 否 | 修改用户某个字段 | | `DELETE` | 删除资源 | ✅ 是 | 删除用户、删除文章 | ```mermaid graph LR A[CRUD] -->|Create| B[POST] A -->|Read| C[GET] A -->|Update| D[PUT / PATCH] A -->|Delete| E[DELETE] ``` > **提问:** 为什么 `GET` 请求要求"幂等"和"安全"(不修改服务器状态)?如果 `GET` 请求能删除数据,会发生什么安全问题? ### 3. 状态码分类 ``` 1xx → 信息性(处理中) 2xx → 成功(200 OK, 201 Created) 3xx → 重定向(301 永久, 302 临时) 4xx → 客户端错误(400 参数错误, 401 未认证, 403 无权限, 404 不存在) 5xx → 服务端错误(500 服务器内部错误, 502 网关错误, 503 服务不可用) ``` > **实战要点:** 前端开发最常遇到的是 401(Token 过期)和 403(权限不足),理解它们的区别很重要:401 是"你是谁?",403 是"你是谁,但你不能做这件事。" ### 4. 常用请求头 | Header | 说明 | |--------|------| | `Content-Type` | 请求体格式(`application/json` / `application/x-www-form-urlencoded`) | | `Authorization` | 认证信息(`Bearer `) | | `Accept` | 期望的响应格式 | | `Cookie` | 客户端存储的会话数据 | | `Referer` | 来源页面(用于防盗链) | | `User-Agent` | 客户端信息(浏览器/设备) | ### 5. RESTful 设计原则 RESTful 不是严格的规范,而是一组设计哲学: ``` 资源命名用名词复数,动词用 HTTP 方法: GET /api/users → 获取所有用户 GET /api/users/:id → 获取单个用户 POST /api/users → 创建用户 PUT /api/users/:id → 更新用户(全量) PATCH /api/users/:id → 更新用户(部分) DELETE /api/users/:id → 删除用户 ``` ```mermaid graph TD A[RESTful 核心原则] --> B["资源用 URL 表示
(名词复数)"] A --> C["操作用 HTTP 方法表示
(GET/POST/PUT/DELETE)"] A --> D["状态码表示结果
(200/201/404/500)"] A --> E["无状态
(每次请求独立)"] A --> F["JSON 作为数据交换格式"] ``` > **思考:** 为什么 RESTful 要求 URL 中用名词而不是动词?`GET /api/deleteUser/5` 和 `DELETE /api/users/5` 哪个更符合 RESTful 原则?为什么? ### 6. Go 后端处理 HTTP 请求示例 ```go package main import ( "encoding/json" "net/http" ) // 定义请求结构体 type CreateUserRequest struct { Name string `json:"name"` Age int `json:"age"` } func handleCreateUser(w http.ResponseWriter, r *http.Request) { // 只接受 POST 方法 if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } // 解析请求体 var req CreateUserRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { http.Error(w, "Invalid request body", http.StatusBadRequest) return } // 处理业务逻辑... // 创建用户 // 返回 201 Created w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(map[string]interface{}{ "id": 1, "name": req.Name, "age": req.Age, }) } ``` ## 关联笔记 - [[API 设计]] — 基于 HTTP 协议的 API 设计方法 - [[数据库基础]] — HTTP 请求最终需要操作数据库 - [[30.areas/finance/Investment lessons/2024.Current trading lessons.md]]