15 种 HTTP 请求方法详解:从 GET/POST 核心方法到 WebDAV 扩展及Python实现示例
目录
- 一、HTTP 请求方法介绍
- 二、HTTP 请求方法详解
- 1. GET
- 2. POST
- 3. PUT
- 4. PATCH
- 5. DELETE
- 6. COPY
- 7. HEAD
- 8. OPTIONS
- 9. LINK
- 10. UNLINK
- 11. PURGE
- 12. LOCK
- 13. UNLOCK
- 14. PROPFIND
- 15. VIEW
- 总结对比
- 三、Python实现示例
一、HTTP 请求方法介绍
HTTP(Hypertext Transfer Protocol)是一种在计算机网络中用于传输超媒体文档的应用层协议。HTTP 协议定义了客户端和服务器之间的通信规则,并规定了客户端向服务器发送请求时需要采用的请求方法(请求方式)。
- 核心方法(HTTP 标准):GET、POST、PUT、PATCH、DELETE、HEAD、OPTIONS
- WebDAV 扩展:COPY、LINK、UNLINK、LOCK、UNLOCK、PROPFIND(用于分布式协作)
- 缓存相关:PURGE(缓存控制)
- 扩展用途:VIEW(自定义视图)
选择HTTP请求方法时需遵循语义:读取用 GET,创建用 POST,全量更新用 PUT,部分更新用 PATCH,删除用 DELETE,元数据查询用 HEAD/PROPFIND 等。
二、HTTP 请求方法详解
- HTTP 请求方法定义了客户端与服务器交互的行为,不同方法对应不同的资源操作语义。以下是对 15 种常见请求方法的详细介绍:
1. GET
- 定义:用于请求获取指定 URI 的资源(读取操作)。
- 用途:最常用的方法,如访问网页、查询数据(如
/users?id=1
)。 - 安全 / 幂等性:
- 安全(不会修改服务器资源状态);
- 幂等(多次调用结果相同,不会产生副作用)。
- 请求体:通常无请求体,参数通过 URL 的查询字符串(
?key=value
)传递。 - 特点:
- 缓存友好(浏览器和代理会缓存 GET 响应);
- URL 长度有限制(不同浏览器限制不同,通常建议不超过 2048 字符);
- 不适合传递敏感数据(参数暴露在 URL 中)。
2. POST
- 定义:用于向服务器提交数据,通常用于创建资源或触发非幂等操作。
- 用途:表单提交(如登录、注册)、上传文件、创建新资源(如
/users
创建用户)。 - 安全 / 幂等性:
- 不安全(可能修改服务器资源);
- 非幂等(多次调用可能产生不同结果,如重复提交订单)。
- 请求体:必须包含请求体,数据格式可自定义(如
application/json
、multipart/form-data
)。 - 特点:
- 参数在请求体中,无长度限制,适合传递敏感数据;
- 服务器通常会为 POST 创建的资源分配新 URI(如返回
201 Created
和Location
头); - 默认不被缓存。
3. PUT
- 定义:用于全量更新指定 URI 的资源,若资源不存在则创建(需客户端指定 URI)。
- 用途:更新资源的完整信息(如
/users/1
全量替换用户 ID=1 的信息)。 - 安全 / 幂等性:
- 不安全(会修改资源);
- 幂等(多次调用结果相同,例如 “将资源替换为 X”,多次执行后资源仍是 X)。
- 请求体:必须包含完整的资源表示(如完整的用户信息 JSON)。
- 特点:
- 与 POST 的区别:PUT 是 “客户端指定 URI” 的创建 / 全量更新,POST 是 “服务器分配 URI” 的创建;
- 若资源不存在,服务器可能返回
201 Created
;若存在,返回200 OK
或204 No Content
。
4. PATCH
- 定义:用于部分更新指定 URI 的资源(仅修改资源的部分字段)。
- 用途:更新资源的局部信息(如
/users/1
仅修改用户的 “手机号” 字段)。 - 安全 / 幂等性:
- 不安全(会修改资源);
- 非幂等(默认不保证幂等,取决于操作逻辑:如 “将年龄 + 1” 多次调用会累加,而 “将年龄设为 20” 则幂等)。
- 请求体:仅包含需要修改的字段(如
{"phone": "13800138000"}
)。 - 特点:
- 与 PUT 的区别:PUT 需传递完整资源,PATCH 仅传递增量修改;
- 需配合
Content-Type: application/json-patch+json
等格式明确修改规则。
5. DELETE
- 定义:用于删除指定 URI 的资源。
- 用途:删除资源(如
/users/1
删除用户 ID=1)。 - 安全 / 幂等性:
- 不安全(会删除资源);
- 幂等(多次调用结果相同:第一次删除后,后续调用仍返回 “资源不存在”)。
- 请求体:通常无请求体(部分场景可能携带删除原因)。
- 特点:
- 成功删除返回
204 No Content
(无响应体)或200 OK
(带说明); - 若资源不存在,可能返回
404 Not Found
。
- 成功删除返回
6. COPY
- 定义:用于复制指定 URI 的资源到目标 URI(扩展方法,常见于 WebDAV 协议)。
- 用途:复制文件或资源(如将
/docs/file1.txt
复制到/docs/file2.txt
)。 - 安全 / 幂等性:
- 不安全(会创建新资源);
- 幂等(多次复制同一资源到同一目标,结果相同)。
- 请求体:通常无请求体,目标 URI 通过
Destination
请求头指定(如Destination: /docs/file2.txt
)。 - 特点:
- 成功复制返回
201 Created
(目标不存在时)或204 No Content
(目标已存在且被覆盖时); - 若源资源不存在,返回
404 Not Found
。
- 成功复制返回
7. HEAD
- 定义:与 GET 类似,但仅返回响应头(无响应体)。
- 用途:获取资源的元数据(如检查资源是否存在、获取文件大小、修改时间等)。
- 安全 / 幂等性:
- 安全(不修改资源);
- 幂等(与 GET 一致,多次调用结果相同)。
- 请求体:无请求体(同 GET)。
- 特点:
- 常用于:检查链接有效性(避免下载完整内容)、获取缓存策略(如
Last-Modified
); - 响应头与 GET 完全一致,仅缺少响应体。
- 常用于:检查链接有效性(避免下载完整内容)、获取缓存策略(如
8. OPTIONS
- 定义:用于请求服务器支持的 HTTP 方法(或跨域预检请求)。
- 用途:
- 查询服务器对指定 URI 支持的方法(如
OPTIONS /users
返回Allow: GET, POST, PUT
); - 跨域资源共享(CORS)中的预检请求(检查是否允许跨域请求)。
- 查询服务器对指定 URI 支持的方法(如
- 安全 / 幂等性:
- 安全(不修改资源);
- 幂等(多次调用结果相同)。
- 请求体:通常无请求体(预检请求可能包含
Access-Control-Request-*
头)。 - 特点:
- 响应头包含
Allow
(支持的方法)或Access-Control-Allow-*
(CORS 规则); - 对整个服务器查询时,URI 可设为
*
(如OPTIONS * HTTP/1.1
)。
- 响应头包含
9. LINK
- 定义:用于建立两个资源之间的关联关系(扩展方法,常见于 WebDAV)。
- 用途:为资源添加关联(如将
/articles/1
与/authors/1
关联为 “作者” 关系)。 - 安全 / 幂等性:
- 不安全(会修改资源的关联状态);
- 非幂等(多次建立相同关联可能导致重复)。
- 请求体:无请求体,关联关系通过
Link
请求头指定(如Link: </authors/1>; rel="author"
)。 - 特点:
- 关联关系通常通过
rel
参数定义(如rel="parent"
“rel=“related”`); - 成功返回
200 OK
或204 No Content
。
- 关联关系通常通过
10. UNLINK
- 定义:用于解除两个资源之间的关联关系(LINK 的反向操作)。
- 用途:删除资源的关联(如解除
/articles/1
与/authors/1
的 “作者” 关联)。 - 安全 / 幂等性:
- 不安全(会修改资源的关联状态);
- 幂等(多次解除同一关联,结果相同)。
- 请求体:无请求体,通过
Link
头指定需解除的关联。 - 特点:若关联不存在,可能返回
404 Not Found
。
11. PURGE
- 定义:用于清除服务器(或缓存服务器)中指定资源的缓存(非标准方法,常见于 CDN 或缓存系统)。
- 用途:强制刷新缓存(如 Varnish、Nginx 缓存中清除
/static/js/app.js
的缓存)。 - 安全 / 幂等性:
- 不安全(会修改缓存状态);
- 幂等(多次清除同一资源缓存,结果相同)。
- 请求体:通常无请求体,目标资源通过 URI 指定。
- 特点:
- 仅缓存服务器或配置了缓存的服务器支持;
- 成功返回
200 OK
(缓存已清除),资源未缓存返回404 Not Found
。
12. LOCK
- 定义:用于锁定资源,防止并发修改(WebDAV 协议核心方法)。
- 用途:多人协作时锁定资源(如编辑文档时防止他人同时修改)。
- 安全 / 幂等性:
- 不安全(会修改资源的锁定状态);
- 非幂等(多次锁定可能导致锁冲突或更新锁超时时间)。
- 请求体:包含锁信息(如锁类型:排他锁 / 共享锁、超时时间)。
- 特点:
- 服务器返回
Lock-Token
头(解锁时需携带); - 支持排他锁(仅一个客户端可修改)和共享锁(多个客户端可读取)。
- 服务器返回
13. UNLOCK
- 定义:用于释放通过 LOCK 锁定的资源(WebDAV 协议)。
- 用途:解锁资源,允许其他客户端修改。
- 安全 / 幂等性:
- 不安全(会修改资源的锁定状态);
- 幂等(多次解锁同一资源,结果相同)。
- 请求体:无请求体,需通过
Lock-Token
请求头携带锁令牌。 - 特点:若锁已过期或令牌无效,返回
409 Conflict
或412 Precondition Failed
。
14. PROPFIND
- 定义:用于获取资源的属性(元数据)(WebDAV 协议方法)。
- 用途:查询资源的元数据(如创建时间、大小、作者等,区别于 GET 获取内容)。
- 安全 / 幂等性:
- 安全(不修改资源);
- 幂等(多次调用结果相同)。
- 请求体:可包含需要查询的属性列表(如
<?xml ...><propfind><prop><getlastmodified /></prop></propfind>
)。 - 特点:
- 通过
Depth
头指定查询深度(0
:仅当前资源;1
:当前资源 + 直接子资源); - 响应为 XML 格式,包含请求的属性值。
- 通过
15. VIEW
- 定义:用于获取资源的特定 “视图”(非标准方法,扩展用途)。
- 用途:返回资源的特定表示形式(如同一数据的 “精简视图”“详情视图”,或根据用户角色返回不同内容)。
- 安全 / 幂等性:
- 安全(通常仅读取资源);
- 幂等(多次调用同一视图,结果相同)。
- 请求体:可能包含视图参数(如
{"view": "brief"}
)。 - 特点:
- 非 HTTP 标准方法,需服务器自定义实现;
- 用于补充 GET 无法满足的多视图需求(如避免 URL 参数过度复杂)。
总结对比
方法 | 幂等性 | 修改资源 | 常见用途 |
---|---|---|---|
GET | ✅ | ❌ | 获取数据 |
POST | ❌ | ✅ | 提交数据、创建资源 |
PUT | ✅ | ✅ | 更新/替换资源 |
PATCH | ❌ | ✅ | 局部更新资源 |
DELETE | ✅ | ✅ | 删除资源 |
COPY | ✅ | ✅ | 复制资源(WebDAV) |
HEAD | ✅ | ❌ | 获取元数据 |
OPTIONS | ✅ | ❌ | 获取服务器支持的方法 |
LINK/UNLINK | ✅ | ✅ | 关联/解除资源关系(WebDAV) |
PURGE | ❌ | ✅ | 清除缓存 |
LOCK/UNLOCK | ❌ | ✅ | 锁定/解锁资源(WebDAV) |
PROPFIND | ✅ | ❌ | 查询资源属性(WebDAV) |
VIEW | ❓ | ❓ | 自定义用途 |
三、Python实现示例
- HTTP 请求方法的Python实现示例
import requestsdef http_get_example():"""GET方法示例:获取资源"""url = 'https://api.example.com/users'params = {'page': 1, 'limit': 10}response = requests.get(url, params=params)print(f"GET 状态码: {response.status_code}")print(f"GET 响应内容: {response.json()}\n")def http_post_example():"""POST方法示例:创建资源"""url = 'https://api.example.com/users'data = {'name': 'John Doe','email': 'john@example.com'}response = requests.post(url, json=data)print(f"POST 状态码: {response.status_code}")print(f"POST 创建的资源: {response.json()}\n")def http_put_example():"""PUT方法示例:完整更新资源"""url = 'https://api.example.com/users/1'data = {'id': 1,'name': 'John Doe Updated','email': 'john.updated@example.com'}response = requests.put(url, json=data)print(f"PUT 状态码: {response.status_code}")print(f"PUT 更新后的资源: {response.json()}\n")def http_patch_example():"""PATCH方法示例:部分更新资源"""url = 'https://api.example.com/users/1'data = {'email': 'john.new@example.com' # 只更新邮箱字段}response = requests.patch(url, json=data)print(f"PATCH 状态码: {response.status_code}")print(f"PATCH 部分更新后的资源: {response.json()}\n")def http_delete_example():"""DELETE方法示例:删除资源"""url = 'https://api.example.com/users/1'response = requests.delete(url)print(f"DELETE 状态码: {response.status_code}")if response.status_code == 204:print("DELETE 资源删除成功\n")def http_head_example():"""HEAD方法示例:获取资源头部信息"""url = 'https://api.example.com/users'response = requests.head(url)print(f"HEAD 状态码: {response.status_code}")print(f"HEAD 响应头: {dict(response.headers)}\n")def http_options_example():"""OPTIONS方法示例:获取服务器支持的方法"""url = 'https://api.example.com/users'response = requests.options(url)print(f"OPTIONS 状态码: {response.status_code}")print(f"OPTIONS 允许的方法: {response.headers.get('Allow')}\n")def http_copy_example():"""COPY方法示例:复制资源"""source_url = 'https://webdav.example.com/docs/report.txt'destination_url = 'https://webdav.example.com/archive/report_backup.txt'response = requests.request('COPY', source_url,headers={'Destination': destination_url})print(f"COPY 状态码: {response.status_code}")if response.status_code in (201, 204):print("COPY 资源复制成功\n")def http_link_example():"""LINK方法示例:建立资源链接"""url = 'https://api.example.com/articles/123'link_url = 'https://api.example.com/categories/tech'response = requests.request('LINK', url,headers={'Link': f'<{link_url}>; rel="category"'})print(f"LINK 状态码: {response.status_code}")if response.status_code == 200:print("LINK 链接建立成功\n")def http_unlink_example():"""UNLINK方法示例:移除资源链接"""url = 'https://api.example.com/articles/123'link_url = 'https://api.example.com/categories/tech'response = requests.request('UNLINK', url,headers={'Link': f'<{link_url}>; rel="category"'})print(f"UNLINK 状态码: {response.status_code}")if response.status_code == 200:print("UNLINK 链接已移除\n")def http_purge_example():"""PURGE方法示例:清除缓存"""url = 'https://cdn.example.com/static/js/app.js'response = requests.request('PURGE', url)print(f"PURGE 状态码: {response.status_code}")if response.status_code == 200:print("PURGE 缓存已清除\n")def http_lock_example():"""LOCK方法示例:锁定资源"""url = 'https://webdav.example.com/docs/report.txt'response = requests.request('LOCK', url,headers={'Depth': '0','Content-Type': 'application/xml'},data='''<?xml version="1.0"?><d:lockinfo xmlns:d="DAV:"><d:lockscope><d:exclusive/></d:lockscope><d:locktype><d:write/></d:locktype><d:owner>John Doe</d:owner></d:lockinfo>''')print(f"LOCK 状态码: {response.status_code}")if response.status_code == 200:print(f"LOCK 锁定令牌: {response.headers.get('Lock-Token')}\n")def http_unlock_example():"""UNLOCK方法示例:解锁资源"""url = 'https://webdav.example.com/docs/report.txt'lock_token = '<urn:uuid:12345678-1234-5678-1234-567812345678>'response = requests.request('UNLOCK', url,headers={'Lock-Token': lock_token})print(f"UNLOCK 状态码: {response.status_code}")if response.status_code == 204:print("UNLOCK 资源已解锁\n")def http_propfind_example():"""PROPFIND方法示例:获取资源属性"""url = 'https://webdav.example.com/docs/'response = requests.request('PROPFIND', url,headers={'Depth': '1','Content-Type': 'application/xml'},data='''<?xml version="1.0"?><d:propfind xmlns:d="DAV:"><d:prop><d:displayname/><d:getlastmodified/></d:prop></d:propfind>''')print(f"PROPFIND 状态码: {response.status_code}")print(f"PROPFIND 响应内容长度: {len(response.text)}\n")def http_view_example():"""VIEW方法示例:获取资源特定表现形式"""url = 'https://api.example.com/reports/123'response = requests.request('VIEW', url,headers={'Accept': 'application/pdf'})print(f"VIEW 状态码: {response.status_code}")if response.status_code == 200:print(f"VIEW 响应内容类型: {response.headers.get('Content-Type')}\n")if __name__ == "__main__":# 注意:这些示例使用了虚构的URL,实际运行时需要替换为真实的API端点http_get_example()http_post_example()http_put_example()http_patch_example()http_delete_example()http_head_example()http_options_example()# 以下方法在普通API中较少见,主要用于特定场景# http_copy_example()# http_link_example()# http_unlink_example()# http_purge_example()# http_lock_example()# http_unlock_example()# http_propfind_example()# http_view_example()