76 lines
3.8 KiB
Markdown
76 lines
3.8 KiB
Markdown
你提供的这段内容非常关键,它展示了微信支付API要求的 `multipart/form-data` 请求体的**原始格式**。
|
||
|
||
你看到的 `--boundary`、`Content-Disposition` 和空行,正是 HTTP 协议中 `multipart/form-data` 的标准结构。
|
||
|
||
好消息是,**你完全不需要手动去拼接这些字符串**(比如手动加 `\r\n` 或 `--boundary`)。Python 的 `requests`
|
||
库可以自动帮你完成这些繁琐的工作,只要你的参数格式正确。
|
||
|
||
针对你提供的这段结构,核心在于如何处理 `meta` 字段。在 `requests` 的 `files` 参数中,`meta` 被视为一个**内容为 JSON
|
||
字符串的“虚拟文件”**。
|
||
|
||
以下是完全对应你提供的 Body 结构的 Python 代码实现:
|
||
|
||
### 🎯 核心代码实现
|
||
|
||
```python
|
||
import requests
|
||
import json
|
||
|
||
url = "https://api.mch.weixin.qq.com/v3/..." # 你的接口地址
|
||
|
||
# 1. 准备 meta 的数据(字典)
|
||
meta_data = {
|
||
"filename": "filea.jpg",
|
||
"sha256": "hjkahkjsjkfsjk78687dhjahdajhk"
|
||
}
|
||
|
||
# 2. 准备文件二进制数据
|
||
# 对应你描述中的 "pic1 //媒体图片的二进制内容"
|
||
with open("filea.jpg", "rb") as f:
|
||
file_binary = f.read()
|
||
|
||
# 3. 构造 files 参数
|
||
# 这里的关键是:meta 也要当作一个“文件”来处理,但它的“内容”是 JSON 字符串
|
||
files = {
|
||
# 对应 Body 中的第一部分:name="meta"
|
||
# 格式:(文件名, 内容, 内容类型)
|
||
# 注意:meta 没有实际文件名,所以第一个参数填 None
|
||
'meta': (None, json.dumps(meta_data), 'application/json'),
|
||
|
||
# 对应 Body 中的第二部分:name="file"; filename="filea.jpg"
|
||
'file': ('filea.jpg', file_binary, 'image/jpeg')
|
||
}
|
||
|
||
# 4. 发送请求
|
||
# 注意:不要设置 Content-Type 头,requests 会自动生成包含 boundary 的正确头
|
||
response = requests.post(url, files=files)
|
||
|
||
print(response.text)
|
||
```
|
||
|
||
### 🔍 代码与你提供的 Body 的对应关系
|
||
|
||
为了让你更放心,我把 `requests` 库自动生成的请求体和你手写的结构做一个对比:
|
||
|
||
| 你的手写结构 (Body) | Python `requests` 的处理逻辑 |
|
||
|:------------------------------------|:----------------------------------------------------|
|
||
| `--boundary` | **自动生成**:库会随机生成一个 boundary 字符串。 |
|
||
| `name="meta"` | **`'meta': ...`**:字典的键对应 `name`。 |
|
||
| `Content-Type: application/json` | **`'application/json'`**:元组的第三个参数指定了内容类型。 |
|
||
| `{ "filename": ... }` | **`json.dumps(...)`**:这是元组的第二个参数(内容),必须是字符串。 |
|
||
| `name="file"; filename="filea.jpg"` | **`'file': ('filea.jpg', ...)`**:元组的第一个参数指定了上传的文件名。 |
|
||
| `pic1 (二进制内容)` | **`file_binary`**:元组的第二个参数,即读取到的二进制数据。 |
|
||
| `--boundary--` | **自动添加**:请求结束时,库会自动加上结束标记。 |
|
||
|
||
### ⚠️ 常见错误提醒
|
||
|
||
1. **不要手动设置 `Content-Type`**:
|
||
如果你手动写 `headers={'Content-Type': 'multipart/form-data'}`,你会丢失 `boundary=...`
|
||
这一关键参数,导致微信服务器无法解析,报错“参数格式错误”。让 `requests` 自己处理这个头。
|
||
|
||
2. **`meta` 必须是字符串**:
|
||
千万不要把 `meta` 放在 `data` 参数里(如 `data={'meta': ...}`),也不要直接传字典。必须放在 `files` 里,并且内容要用
|
||
`json.dumps()` 转成字符串。
|
||
|
||
3. **文件名后缀**:
|
||
微信支付对图片格式有要求(JPG, BMP, PNG),确保你的 `filename` 后缀和实际文件内容一致。 |