请谈谈-HTTP-中的请求方法GETPOSTPUTDELETE等,它们的区别是什么
请谈谈 HTTP 中的请求方法(GET、POST、PUT、DELETE等),它们的区别是什么?
一、HTTP方法核心概念
HTTP请求方法是客户端向服务器表达操作意图的核心标识,遵循RFC 7231等规范定义。 正确使用方法可提升API语义清晰度,降低前后端协作成本。以下是常见方法特性对比表:
方法 | 幂等性 | 安全性 | 请求体支持 | 典型应用场景 |
---|---|---|---|---|
GET | 是 | 是 | 否 | 获取资源列表/详情 |
POST | 否 | 否 | 是 | 创建资源/触发复杂操作 |
PUT | 是 | 否 | 是 | 全量替换资源 |
DELETE | 是 | 否 | 否 | 删除指定资源 |
PATCH | 否 | 否 | 是 | 部分更新资源 |
二、核心方法详解与代码示例
1 GET:安全的数据获取
// 获取用户列表(带查询参数)
async function fetchUsers(page = 1) {
const query = new URLSearchParams({ page })
const response = await fetch(/api/users?${query}
)
if (!response.ok) {
throw new Error(获取失败: ${response.status}
)
}
return response.json()
}
安全实践 :
- 避免在URL中传递敏感参数(会被浏览器历史记录)
- 对数组参数进行编码处理:
ids[]=1&ids[]=2
2 POST:非幂等的资源创建
// 创建新用户(带CSRF保护) async function createUser(userData) { const csrfToken = document.querySelector(‘meta[name=“csrf-token”]’).content const response = await fetch(’/api/users’, { method: ‘POST’, headers: { ‘Content-Type’: ‘application/json’, ‘X-CSRF-Token’: csrfToken }, body: JSON.stringify(userData) }) if (response.status === 201) { return response.headers.get(‘Location’) // 获取新资源路径 } const error = await response.json() throw new Error(error.message) } 开发陷阱 :
- 多次点击提交按钮会导致重复创建(需前端防抖+服务端幂等校验)
- 文件上传需使用
multipart/form-data
格式
3 PUT:幂等的全量替换
// 更新用户全部信息
async function updateUser(userId, newData) {
const response = await fetch(/api/users/${userId}
, {
method: ‘PUT’,
headers: { ‘Content-Type’: ‘application/json’ },
body: JSON.stringify(newData)
})
if (response.status === 204) { // 204 No Content常见响应
return true
}
if (response.status === 409) { // 版本冲突处理
return handleConflict(await response.json())
}
throw new Error(‘更新失败’)
}
注意事项 :
- 要求客户端传递完整资源对象
- 需配合
ETag
或Last-Modified
处理并发冲突
4 DELETE:资源删除操作
// 带确认的删除操作
async function deleteResource(resourceId) {
if (!confirm(‘确定删除?’)) return
const response = await fetch(/api/resources/${resourceId}
, {
method: ‘DELETE’
})
if (response.status === 204) {
showToast(‘删除成功’)
refreshList()
} else if (response.status === 403) {
showError(‘权限不足’)
}
}
特殊场景 :
- 软删除建议返回200+状态字段而非204
- 批量删除推荐使用POST + 请求体(避免URL长度限制)
三、高级方法实战应用
1 PATCH:部分更新
// 使用JSON Patch格式
async function updateUserEmail(userId, newEmail) {
const patch = [
{ op: ‘replace’, path: ‘/email’, value: newEmail }
]
const response = await fetch(/api/users/${userId}
, {
method: ‘PATCH’,
headers: { ‘Content-Type’: ‘application/json-patch+json’ },
body: JSON.stringify(patch)
})
// 处理422 Unprocessable Entity验证错误
}
规范建议 :
- 使用标准格式:JSON Patch(RFC 6902)或JSON Merge Patch
- 避免在数组中指定索引(易引发并发问题)
2 OPTIONS:预检请求处理
// CORS预检请求处理示例 app.options(’/api/*’, (req, res) => { res.setHeader(‘Access-Control-Allow-Methods’, ‘GET, POST, PUT, DELETE’) res.setHeader(‘Access-Control-Allow-Headers’, ‘Content-Type, Authorization’) res.status(204).end() }) 性能优化 :
- 设置
Access-Control-Max-Age
减少预检次数 - 避免在Authorization头携带过大token
四、常见误区与最佳实践
1 方法误用反模式
// 错误示例:用GET执行删除操作
fetch(/api/users/123?action=delete
, { method: ‘GET’ })
// 正确做法:使用DELETE方法
fetch(/api/users/123
, { method: ‘DELETE’ })
风险点 :
- 搜索引擎爬虫可能触发危险操作
- 浏览器预加载可能导致意外执行
2 RESTful API设计规范
// 资源嵌套路由示例 POST /articles/123/comments // 创建评论 GET /articles/123/comments // 获取评论列表 PUT /articles/123/comments/456 // 更新指定评论 设计原则 :
- 使用名词而非动词定义端点
- 版本控制通过Header或URL路径实现(如
/v1/resource
)
3 幂等性保障机制
// 支付接口幂等处理(使用唯一ID) async function processPayment(orderId, idempotencyKey) { const response = await fetch(’/api/payments’, { method: ‘POST’, headers: { ‘Idempotency-Key’: idempotencyKey // 服务端存储该Key保证幂等 }, body: JSON.stringify({ orderId }) }) // 处理409 Conflict重复请求 } 实现方案 :
- 服务端存储请求指纹(方法+路径+参数+Key)
- 客户端生成UUID作为幂等Key
五、调试与性能优化
- Network面板分析
- 查看请求方法列确认是否误用
- 过滤
method:POST
快速定位提交请求
- 性能优化策略 // 批量操作使用PATCH代替多个PUT const bulkUpdate = [ { id: 1, op: ‘replace’, path: ‘/name’, value: ‘Alice’ }, { id: 2, op: ‘remove’, path: ‘/address’ } ] fetch(’/api/users/bulk’, { method: ‘PATCH’, body: JSON.stringify(bulkUpdate) })
- 自动化测试验证 // 使用Jest测试方法合规性 test(‘用户创建必须使用POST方法’, async () => { const response = await app.inject({ method: ‘PUT’, url: ‘/api/users’, payload: mockUserData }) expect(response.statusCode).toBe(405) // Method Not Allowed })
六、总结与团队规范建议
- 强制规范
- 敏感操作禁止使用GET方法
- 更新操作严格区分PUT/PATCH语义
- 协作流程
- API文档必须明确每个端点的允许方法
- 使用Swagger/OpenAPI生成交互式文档
- 监控报警
- 对405 Method Not Allowed进行监控
- 统计非常用方法(如HEAD/OPTIONS)的调用频率
- 安全加固
- 严格限制TRACE/CONNECT方法
- 对敏感接口启用双重认证(如删除操作)
参考资料:
- RFC 7231: HTTP/1.1 Semantics and Content
- RESTful Web APIs by Leonard Richardson
- OWASP REST Security Cheat Sheet