Skip to content

第 3 章 · POST 与请求体构建

本章目标:掌握 POST、PUT、DELETE 等请求方法,学会构建 JSON 表单和多部分表单请求体。

3.1 HTTP 方法一览

除了 GET,常用的 HTTP 方法还有:

方法用途幂等性
GET获取资源
POST创建资源/提交数据
PUT全量更新资源
PATCH部分更新资源
DELETE删除资源
HEAD获取响应头(无 body)
OPTIONS查询支持的方法
python
import requests

base = 'https://httpbin.org'

# GET - 获取
resp = requests.get(f'{base}/get')

# POST - 创建
resp = requests.post(f'{base}/post', json={'key': 'value'})

# PUT - 全量更新
resp = requests.put(f'{base}/put', json={'key': 'value'})

# PATCH - 部分更新
resp = requests.patch(f'{base}/patch', json={'key': 'value'})

# DELETE - 删除
resp = requests.delete(f'{base}/delete')

3.2 JSON 请求体

现代 API 普遍使用 JSON 格式传输数据。requests 提供 json 参数:

python
import requests

# 方法一:使用 json 参数(推荐,自动设置 Content-Type)
resp = requests.post(
    'https://httpbin.org/post',
    json={'name': '张三', 'age': 30, 'tags': ['python', 'ai']}
)
print(resp.json()['json'])  # {'name': '张三', 'age': 30, ...}

# 方法二:手动序列化(适用于需要自定义 Content-Type 的场景)
import json
resp = requests.post(
    'https://httpbin.org/post',
    data=json.dumps({'name': '张三'}),
    headers={'Content-Type': 'application/json'}
)

json 参数会自动:

  • 将 Python 对象序列化为 JSON 字符串
  • 设置 Content-Type: application/json 请求头

3.3 表单请求体

传统的 HTML 表单使用 application/x-www-form-urlencoded 格式:

python
import requests

# 表单数据(自动编码)
resp = requests.post(
    'https://httpbin.org/post',
    data={'username': 'admin', 'password': 'secret123'}
)

# 查看发送的数据
print(resp.json()['form'])  # {'username': 'admin', 'password': 'secret123'}

3.4 文件上传

使用 files 参数上传文件,支持单文件和多文件:

python
import requests

# 上传单个文件
with open('report.pdf', 'rb') as f:
    resp = requests.post(
        'https://httpbin.org/post',
        files={'document': f}
    )

# 上传多个文件
files = [
    ('photos', ('a.jpg', open('a.jpg', 'rb'), 'image/jpeg')),
    ('photos', ('b.jpg', open('b.jpg', 'rb'), 'image/jpeg')),
]
resp = requests.post('https://httpbin.org/post', files=files)

# 自定义文件名和内容类型
resp = requests.post(
    'https://httpbin.org/post',
    files={
        'file': ('custom_name.txt', b'file content', 'text/plain')
    }
)

files 参数接受多种格式:

  • 文件对象:{'file': open('x.pdf', 'rb')}
  • 元组:{'file': ('name.ext', content, 'mime/type')}

3.5 组合请求体

实际场景中,可能同时需要表单字段和文件:

python
import requests

# 表单字段 + 文件
resp = requests.post(
    'https://httpbin.org/post',
    data={'title': '报告', 'category': '技术'},
    files={'document': open('report.pdf', 'rb')}
)

# 复杂场景:多个文件 + 字段
files = [
    ('attachments', ('doc1.pdf', open('doc1.pdf', 'rb'), 'application/pdf')),
    ('attachments', ('doc2.pdf', open('doc2.pdf', 'rb'), 'application/pdf')),
]
data = {
    'project': 'Alpha',
    'description': '季度报告',
    'priority': 'high'
}
resp = requests.post('https://example.com/upload', data=data, files=files)

3.6 httpx 的等效写法

httpx 的 API 与 requests 高度一致:

python
import httpx

# POST with JSON
resp = httpx.post('https://httpbin.org/post', json={'key': 'value'})

# POST with form data
resp = httpx.post('https://httpbin.org/post', data={'key': 'value'})

# File upload
with open('file.txt', 'rb') as f:
    resp = httpx.post('https://httpbin.org/post', files={'file': f})

3.7 本章小结

  • POST/PUT/PATCH/DELETE 方法与 requests 对应函数名相同;
  • JSON 请求体用 json 参数,自动序列化并设置 Content-Type;
  • 表单数据用 data 参数,文件上传用 files 参数;
  • httpx 语法与 requests 高度兼容。

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. requests.post() 的 json 参数和 data 参数有什么区别?

2. 以下哪种方式可以正确上传文件?

3. PUT 和 PATCH 方法的主要区别是?

4. httpx 上传文件时,files 参数的格式与 requests 相比?

🛠️ 动手实践

  1. 用 POST 向 https://httpbin.org/post 发送 JSON 数据,打印返回的 JSON 字段。
  2. 上传一个文本文件到 httpbin,查看服务器接收的文件名和内容。
  3. 组合表单字段和文件上传,模拟一个"提交带附件的表单"场景。