HTTP DELETE 方法:完整指南 (2026)
关于 REST API HTTP DELETE 方法,你需要了解的一切
开始使用 Hypereal 构建
通过单个 API 访问 Kling、Flux、Sora、Veo 等。免费积分开始,扩展到数百万。
无需信用卡 • 10万+ 开发者 • 企业级服务
HTTP DELETE 方法:完整指南 (2026)
HTTP DELETE 方法用于从服务器删除资源。它是 RESTful API 中使用的四种核心 HTTP 方法之一(与 GET、POST 和 PUT 并列),对于任何处理 API 的开发人员来说,了解如何正确使用它都是至关重要的。
本指南将详细介绍 DELETE 方法:它的工作原理、何时使用、如何在客户端和服务器端实现,以及需要避免的常见错误。
什么是 HTTP DELETE 方法?
DELETE 方法请求服务器移除由给定 URI 标识的资源。成功的 DELETE 操作意味着该资源不再存在于该位置。
DELETE /api/v1/users/42 HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9...
服务器返回一个状态码来指示结果:
HTTP/1.1 204 No Content
关键特性
| 属性 | 值 | 说明 |
|---|---|---|
| 请求体 (Request body) | 可选(通常为空) | 大多数实现会忽略请求体 |
| 响应体 (Response body) | 可选 | 204 没有响应体;200 可能包含详细信息 |
| 幂等性 (Idempotent) | 是 | 对同一资源执行两次删除操作会产生相同的结果 |
| 安全性 (Safe) | 否 | 它会修改服务器状态 |
| 可缓存性 (Cacheable) | 否 | 响应不应被缓存 |
DELETE 响应状态码
| 状态码 | 含义 | 何时使用 |
|---|---|---|
| 200 OK | 资源已删除;响应包含详细信息 | 当你需要返回确认信息内容时 |
| 202 Accepted | 删除操作已进入队列等待处理 | 用于异步删除(例如:后台任务) |
| 204 No Content | 资源已删除;无响应体 | DELETE 最常用的响应码 |
| 404 Not Found | 资源不存在 | 如果资源从未被创建过 |
| 401 Unauthorized | 需要身份验证 | 缺失或无效的凭证 |
| 403 Forbidden | 已验证但未授权 | 用户缺乏删除权限 |
| 409 Conflict | 因当前状态无法删除 | 例如:资源有关联的从属记录 |
在 200 和 204 之间做出选择
# 204 No Content -- 最常见,无响应体
DELETE /api/v1/users/42
Response: 204 No Content
# 200 OK -- 当你想返回被删除的资源时
DELETE /api/v1/users/42
Response: 200 OK
Body: {"id": 42, "name": "John", "deleted": true, "deletedAt": "2026-02-06T12:00:00Z"}
当客户端不需要确认细节时使用 204。当客户端需要查看被删除的资源(例如:用于撤销功能或审计日志)时使用 200。
DELETE 实践:客户端示例
cURL
# 简单的 DELETE 请求
curl -X DELETE https://api.example.com/v1/users/42
# 带身份验证的 DELETE
curl -X DELETE \
-H "Authorization: Bearer your_token_here" \
https://api.example.com/v1/users/42
# 带 API 密钥的 DELETE
curl -X DELETE \
-H "X-API-Key: your_api_key" \
https://api.example.com/v1/users/42
JavaScript (Fetch API)
// 基础 DELETE 请求
const response = await fetch("https://api.example.com/v1/users/42", {
method: "DELETE",
headers: {
"Authorization": "Bearer your_token_here",
},
});
if (response.status === 204) {
console.log("User deleted successfully");
} else if (response.status === 404) {
console.log("User not found");
}
JavaScript (Axios)
import axios from "axios";
try {
await axios.delete("https://api.example.com/v1/users/42", {
headers: {
"Authorization": "Bearer your_token_here",
},
});
console.log("Deleted successfully");
} catch (error) {
if (error.response?.status === 404) {
console.log("User not found");
} else if (error.response?.status === 403) {
console.log("Not authorized to delete this user");
}
}
Python (requests)
import requests
response = requests.delete(
"https://api.example.com/v1/users/42",
headers={"Authorization": "Bearer your_token_here"}
)
if response.status_code == 204:
print("Deleted successfully")
elif response.status_code == 404:
print("User not found")
elif response.status_code == 409:
print("Cannot delete: user has dependent records")
Go
package main
import (
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://api.example.com/v1/users/42", nil)
req.Header.Set("Authorization", "Bearer your_token_here")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
switch resp.StatusCode {
case 204:
fmt.Println("Deleted successfully")
case 404:
fmt.Println("User not found")
case 403:
fmt.Println("Not authorized")
}
}
DELETE 实践:服务器端示例
Node.js (Express)
import express from "express";
const app = express();
app.delete("/api/v1/users/:id", async (req, res) => {
const { id } = req.params;
// 检查用户是否存在
const user = await db.users.findById(id);
if (!user) {
return res.status(404).json({ error: "User not found" });
}
// 检查是否有依赖记录
const orders = await db.orders.countByUserId(id);
if (orders > 0) {
return res.status(409).json({
error: "Cannot delete user with active orders",
orderCount: orders,
});
}
// 删除用户
await db.users.deleteById(id);
// 返回 204 No Content
res.status(204).send();
});
Python (FastAPI)
from fastapi import FastAPI, HTTPException
app = FastAPI()
@app.delete("/api/v1/users/{user_id}", status_code=204)
async def delete_user(user_id: int):
user = await db.users.find_by_id(user_id)
if not user:
raise HTTPException(status_code=404, detail="User not found")
if await db.orders.count_by_user_id(user_id) > 0:
raise HTTPException(
status_code=409,
detail="Cannot delete user with active orders"
)
await db.users.delete_by_id(user_id)
# FastAPI 会自动返回 204 且不含响应体
Go (net/http)
func deleteUserHandler(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
user, err := db.FindUserByID(id)
if err != nil || user == nil {
http.Error(w, "User not found", http.StatusNotFound)
return
}
if err := db.DeleteUser(id); err != nil {
http.Error(w, "Failed to delete user", http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusNoContent)
}
幂等性:为什么它很重要
DELETE 方法是幂等的,这意味着多次发出相同的 DELETE 请求会产生相同的结果:资源最终被删除(或不存在)。
DELETE /api/v1/users/42 -> 204 No Content (用户已删除)
DELETE /api/v1/users/42 -> 204 No Content (已经删除,结果一致)
然而,这里有一个细微差别。有些 API 在第二次请求时会返回 404,因为资源已不复存在。这两种方法都是有效的:
| 方案 | 第一次请求 | 第二次请求 | 严格幂等? |
|---|---|---|---|
| 始终 204 | 204 | 204 | 是 |
| 消失则 404 | 204 | 404 | 技术上是(资源状态依然是已删除) |
“始终返回 204”的方案对客户端来说更简单,因为他们不需要区分“刚刚删除”和“已经删除”。
软删除 (Soft Delete) vs 硬删除 (Hard Delete)
在生产系统中,许多团队实施软删除而不是真正地移除数据:
硬删除
-- 数据被永久移除
DELETE FROM users WHERE id = 42;
软删除
-- 数据被标记为已删除但保留在数据库中
UPDATE users SET deleted_at = NOW(), is_active = false WHERE id = 42;
| 特性 | 可恢复性 | 存储空间 | 合规性 | 复杂度 |
|---|---|---|---|---|
| 硬删除 | 否 | 节省空间 | GDPR 友好 | 简单 |
| 软删除 | 是 | 随时间增长 | 需要清理任务 | 中等 |
对于客户端来说,API 终端看起来是一样的 (DELETE /api/v1/users/42)。区别在于服务器端的实现。
批量删除
有时你需要一次删除多个资源。有两种常见模式:
模式 1:查询参数
DELETE /api/v1/users?ids=1,2,3,4,5
模式 2:请求体
curl -X DELETE https://api.example.com/v1/users \
-H "Content-Type: application/json" \
-d '{"ids": [1, 2, 3, 4, 5]}'
模式 3:POST 到删除终端
有些 API 避免在 DELETE 请求中发送 body,转而使用 POST:
POST /api/v1/users/bulk-delete
Body: {"ids": [1, 2, 3, 4, 5]}
模式 3 的兼容性最广,因为某些 HTTP 客户端和代理服务器会剥离 DELETE 请求中的请求体。
常见错误
1. 未检查授权
务必验证调用者是否有权删除该资源:
app.delete("/api/v1/posts/:id", async (req, res) => {
const post = await db.posts.findById(req.params.id);
if (post.authorId !== req.user.id && !req.user.isAdmin) {
return res.status(403).json({ error: "Not authorized" });
}
// ... 执行删除
});
2. 未处理级联删除
删除父资源可能会产生孤立的子记录。请显式处理:
// 删除用户及所有相关数据
await db.transaction(async (tx) => {
await tx.comments.deleteByUserId(userId);
await tx.posts.deleteByUserId(userId);
await tx.sessions.deleteByUserId(userId);
await tx.users.deleteById(userId);
});
3. 危险操作缺少确认
对于关键资源,考虑要求确认参数:
DELETE /api/v1/projects/42?confirm=true
结论
HTTP DELETE 方法在概念上很简单,但需要谨慎实现。始终进行身份验证和授权,处理边缘情况(缺失资源、依赖记录),并根据数据保留策略在软删除和硬删除之间做出选择。
如果你正在构建与媒体生成 API 交互的应用,Hypereal AI 提供了清晰的 REST API,你可以使用 DELETE 方法来管理生成的资产、移除上传的图片或清理已完成的视频生成任务。
