This repository has been archived on 2026-05-19. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
obsidian/BACKEND/HTTP 协议.md
T

4.5 KiB
Raw Blame History

tags, create time
tags create time
后端
HTTP
协议
基础
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 删除资源 ✅ 是 删除用户、删除文章
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 <token>)
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      → 删除用户
graph TD
    A[RESTful 核心原则] --> B["资源用 URL 表示<br/>(名词复数)"]
    A --> C["操作用 HTTP 方法表示<br/>(GET/POST/PUT/DELETE)"]
    A --> D["状态码表示结果<br/>(200/201/404/500)"]
    A --> E["无状态<br/>(每次请求独立)"]
    A --> F["JSON 作为数据交换格式"]

思考: 为什么 RESTful 要求 URL 中用名词而不是动词?GET /api/deleteUser/5 和 DELETE /api/users/5 哪个更符合 RESTful 原则?为什么?

6. Go 后端处理 HTTP 请求示例

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,
    })
}

关联笔记