Skip to content

HTTP协议

概述

HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上应用最广泛的协议,用于在Web浏览器和Web服务器之间传输数据。

核心概念

HTTP是什么

HTTP是一个无状态请求-响应协议,客户端发送请求,服务器返回响应。

特点:

  • 无状态:每个请求都是独立的
  • 基于文本:协议内容是人类可读的
  • 客户端-服务器模式:请求由客户端发起
  • 可扩展:通过HTTP头部扩展功能

HTTP vs HTTPS

特性HTTPHTTPS
安全性明文传输加密传输
端口80443
证书不需要需要SSL/TLS证书
性能较快稍慢(加密开销)

HTTP请求

请求结构

http
GET /api/users HTTP/1.1
Host: api.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Content-Type: application/json

{
  "name": "张三",
  "email": "[email protected]"
}

HTTP方法

GET - 获取资源

http
GET /api/users/123 HTTP/1.1
Host: api.example.com

特点:

  • 幂等:多次请求结果相同
  • 安全:不修改服务器状态
  • 可缓存:响应可以被缓存

POST - 创建资源

http
POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json

{
  "name": "李四",
  "email": "[email protected]"
}

特点:

  • 非幂等:多次请求可能产生不同结果
  • 不安全:可能修改服务器状态
  • 不可缓存:响应通常不被缓存

PUT - 更新资源

http
PUT /api/users/123 HTTP/1.1
Host: api.example.com
Content-Type: application/json

{
  "name": "李四",
  "email": "[email protected]",
  "age": 25
}

特点:

  • 幂等:多次请求结果相同
  • 不安全:修改服务器状态
  • 完整更新:替换整个资源

PATCH - 部分更新

http
PATCH /api/users/123 HTTP/1.1
Host: api.example.com
Content-Type: application/json

{
  "age": 26
}

特点:

  • 幂等:多次请求结果相同
  • 不安全:修改服务器状态
  • 部分更新:只更新指定字段

DELETE - 删除资源

http
DELETE /api/users/123 HTTP/1.1
Host: api.example.com

特点:

  • 幂等:多次请求结果相同
  • 不安全:修改服务器状态

请求头部

常用请求头

http
# 内容类型
Content-Type: application/json
Content-Type: application/x-www-form-urlencoded
Content-Type: multipart/form-data

# 认证
Authorization: Bearer <token>
Authorization: Basic <base64-encoded-credentials>

# 缓存控制
Cache-Control: no-cache
Cache-Control: max-age=3600

# 用户代理
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)

# 接受的内容类型
Accept: application/json
Accept: text/html,application/xhtml+xml

# 语言偏好
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8

# 编码
Accept-Encoding: gzip, deflate, br

HTTP响应

响应结构

http
HTTP/1.1 200 OK
Date: Mon, 15 Jan 2024 10:30:00 GMT
Content-Type: application/json
Content-Length: 123
Cache-Control: max-age=3600

{
  "id": 123,
  "name": "张三",
  "email": "[email protected]"
}

HTTP状态码

1xx - 信息性状态码

  • 100 Continue: 继续请求
  • 101 Switching Protocols: 切换协议

2xx - 成功状态码

  • 200 OK: 请求成功
  • 201 Created: 资源创建成功
  • 202 Accepted: 请求已接受,正在处理
  • 204 No Content: 请求成功,无返回内容

3xx - 重定向状态码

  • 301 Moved Permanently: 永久重定向
  • 302 Found: 临时重定向
  • 304 Not Modified: 资源未修改
  • 307 Temporary Redirect: 临时重定向(保持方法)

4xx - 客户端错误状态码

  • 400 Bad Request: 请求语法错误
  • 401 Unauthorized: 未授权
  • 403 Forbidden: 禁止访问
  • 404 Not Found: 资源不存在
  • 405 Method Not Allowed: 方法不允许
  • 409 Conflict: 资源冲突
  • 422 Unprocessable Entity: 无法处理的实体

5xx - 服务器错误状态码

  • 500 Internal Server Error: 服务器内部错误
  • 501 Not Implemented: 功能未实现
  • 502 Bad Gateway: 网关错误
  • 503 Service Unavailable: 服务不可用
  • 504 Gateway Timeout: 网关超时

响应头部

常用响应头

http
# 内容类型
Content-Type: application/json
Content-Type: text/html; charset=utf-8

# 缓存控制
Cache-Control: public, max-age=3600
Cache-Control: private, no-cache
Cache-Control: no-store

# 安全相关
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block

# CORS
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization

# 内容长度
Content-Length: 1234

# 压缩
Content-Encoding: gzip

实际应用

RESTful API设计

javascript
// 用户资源API示例
const express = require('express');
const app = express();

// GET /users - 获取用户列表
app.get('/users', (req, res) => {
  const users = getUserList();
  res.json({
    data: users,
    total: users.length,
    page: parseInt(req.query.page) || 1
  });
});

// GET /users/:id - 获取单个用户
app.get('/users/:id', (req, res) => {
  const user = getUserById(req.params.id);
  if (!user) {
    return res.status(404).json({ error: '用户不存在' });
  }
  res.json({ data: user });
});

// POST /users - 创建用户
app.post('/users', (req, res) => {
  const newUser = createUser(req.body);
  res.status(201).json({ data: newUser });
});

// PUT /users/:id - 更新用户
app.put('/users/:id', (req, res) => {
  const updatedUser = updateUser(req.params.id, req.body);
  if (!updatedUser) {
    return res.status(404).json({ error: '用户不存在' });
  }
  res.json({ data: updatedUser });
});

// DELETE /users/:id - 删除用户
app.delete('/users/:id', (req, res) => {
  const deleted = deleteUser(req.params.id);
  if (!deleted) {
    return res.status(404).json({ error: '用户不存在' });
  }
  res.status(204).send();
});

错误处理

javascript
// 统一错误处理中间件
app.use((err, req, res, next) => {
  console.error(err.stack);
  
  // 根据错误类型返回不同状态码
  if (err.name === 'ValidationError') {
    return res.status(400).json({
      error: '数据验证失败',
      details: err.message
    });
  }
  
  if (err.name === 'UnauthorizedError') {
    return res.status(401).json({
      error: '未授权访问'
    });
  }
  
  // 默认500错误
  res.status(500).json({
    error: '服务器内部错误'
  });
});

缓存策略

javascript
// 缓存中间件
const cache = new Map();

app.get('/api/products/:id', (req, res) => {
  const productId = req.params.id;
  const cacheKey = `product:${productId}`;
  
  // 检查缓存
  if (cache.has(cacheKey)) {
    const cached = cache.get(cacheKey);
    if (Date.now() - cached.timestamp < 300000) { // 5分钟缓存
      res.set('X-Cache', 'HIT');
      return res.json(cached.data);
    }
  }
  
  // 从数据库获取数据
  const product = getProductFromDatabase(productId);
  
  // 设置缓存
  cache.set(cacheKey, {
    data: product,
    timestamp: Date.now()
  });
  
  res.set('X-Cache', 'MISS');
  res.json(product);
});

安全考虑

HTTPS的重要性

javascript
// 强制HTTPS重定向
app.use((req, res, next) => {
  if (req.header('x-forwarded-proto') !== 'https') {
    res.redirect(`https://${req.header('host')}${req.url}`);
  } else {
    next();
  }
});

安全头部设置

javascript
// 安全头部中间件
app.use((req, res, next) => {
  // 防止点击劫持
  res.setHeader('X-Frame-Options', 'DENY');
  
  // 防止MIME类型嗅探
  res.setHeader('X-Content-Type-Options', 'nosniff');
  
  // XSS保护
  res.setHeader('X-XSS-Protection', '1; mode=block');
  
  // 内容安全策略
  res.setHeader('Content-Security-Policy', 
    "default-src 'self'; script-src 'self' 'unsafe-inline'");
  
  next();
});

请求限制

javascript
const rateLimit = require('express-rate-limit');

// 限制登录请求频率
const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分钟
  max: 5, // 最多5次请求
  message: {
    error: '登录尝试过于频繁,请稍后再试'
  }
});

app.post('/login', loginLimiter, (req, res) => {
  // 登录逻辑
});

性能优化

压缩响应

javascript
const compression = require('compression');

// 启用gzip压缩
app.use(compression({
  level: 6,
  threshold: 1024 // 只压缩大于1KB的响应
}));

连接池

javascript
// 数据库连接池配置
const mysql = require('mysql2/promise');

const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'myapp',
  connectionLimit: 10,
  acquireTimeout: 60000,
  timeout: 60000,
  reconnect: true
});

调试工具

使用curl测试API

bash
# GET请求
curl -X GET "https://api.example.com/users" \
  -H "Authorization: Bearer your-token" \
  -H "Content-Type: application/json"

# POST请求
curl -X POST "https://api.example.com/users" \
  -H "Content-Type: application/json" \
  -d '{"name":"张三","email":"[email protected]"}'

# 查看响应头
curl -I "https://api.example.com/users"

浏览器开发者工具

javascript
// 在浏览器控制台测试API
fetch('/api/users', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer your-token',
    'Content-Type': 'application/json'
  }
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

总结

HTTP协议是Web开发的基础,理解HTTP的工作原理对于构建高质量的Web应用至关重要:

  1. 请求-响应模式: 客户端发起请求,服务器返回响应
  2. 无状态协议: 每个请求都是独立的
  3. 状态码分类: 1xx信息,2xx成功,3xx重定向,4xx客户端错误,5xx服务器错误
  4. 安全考虑: 使用HTTPS,设置安全头部,实施请求限制
  5. 性能优化: 启用压缩,使用缓存,配置连接池

掌握HTTP协议是成为优秀后端开发者的必备技能。