HTTP协议
概述
HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上应用最广泛的协议,用于在Web浏览器和Web服务器之间传输数据。
核心概念
HTTP是什么
HTTP是一个无状态的请求-响应协议,客户端发送请求,服务器返回响应。
特点:
- 无状态:每个请求都是独立的
- 基于文本:协议内容是人类可读的
- 客户端-服务器模式:请求由客户端发起
- 可扩展:通过HTTP头部扩展功能
HTTP vs HTTPS
特性 | HTTP | HTTPS |
---|---|---|
安全性 | 明文传输 | 加密传输 |
端口 | 80 | 443 |
证书 | 不需要 | 需要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应用至关重要:
- 请求-响应模式: 客户端发起请求,服务器返回响应
- 无状态协议: 每个请求都是独立的
- 状态码分类: 1xx信息,2xx成功,3xx重定向,4xx客户端错误,5xx服务器错误
- 安全考虑: 使用HTTPS,设置安全头部,实施请求限制
- 性能优化: 启用压缩,使用缓存,配置连接池
掌握HTTP协议是成为优秀后端开发者的必备技能。