API 文件上传是开发者在调用 AI 视频生成、图像处理等接口时经常遇到的技术需求。本文将系统讲解 multipart/form-data 编码方式的工作原理,并以 Sora 2 图生视频 API 为例,帮助你掌握 API 文件上传的核心技能。
核心价值: 读完本文,你将完全理解 multipart/form-data 的底层机制,学会使用 curl -F 命令进行文件上传,并能独立实现 Sora 2 等 AI API 的图片上传功能。

API 文件上传核心知识
在深入代码之前,我们需要理解为什么 API 文件上传需要使用特殊的编码方式。
为什么需要 multipart/form-data
当你通过 API 发送普通的文本数据时,可以使用简单的 application/x-www-form-urlencoded 编码。然而,这种方式在处理文件时存在严重问题:
| 编码类型 | 适用场景 | 文件处理能力 | 效率 |
|---|---|---|---|
application/x-www-form-urlencoded |
简单键值对 | ❌ 不适合 | 二进制需 URL 转义,效率低 |
application/json |
结构化数据 | ⚠️ 需 Base64 编码 | 体积增大 33% |
multipart/form-data |
文件上传 | ✅ 原生支持 | 无需编码,高效 |
multipart/form-data 是 1998 年 RFC 2388 标准提出的方案,专门解决 HTTP 协议中混合发送文本和二进制数据的问题。
multipart/form-data 工作原理
multipart/form-data 的核心思想是将一个 HTTP 请求体分割成多个独立的「部分」(parts),每个部分可以有自己的内容类型。

数据结构详解
一个典型的 multipart/form-data 请求包含以下结构:
POST /v1/videos HTTP/1.1
Host: api.apiyi.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxk
------WebKitFormBoundary7MA4YWxk
Content-Disposition: form-data; name="prompt"
She turns around and smiles
------WebKitFormBoundary7MA4YWxk
Content-Disposition: form-data; name="model"
sora-2-pro
------WebKitFormBoundary7MA4YWxk
Content-Disposition: form-data; name="input_reference"; filename="sample.jpeg"
Content-Type: image/jpeg
[二进制图片数据]
------WebKitFormBoundary7MA4YWxk--
| 组件 | 作用 | 示例 |
|---|---|---|
| Boundary | 分隔各个数据部分的唯一标识符 | ----WebKitFormBoundary7MA4YWxk |
| Content-Disposition | 描述该部分的元数据 | form-data; name="prompt" |
| Content-Type | 该部分的 MIME 类型 | image/jpeg |
| Body | 实际数据内容 | 文本或二进制数据 |
🎯 技术要点: Boundary 必须是请求体中不会出现的唯一字符串。服务器通过 boundary 来解析和分离各个数据部分。
curl -F 命令详解: API 文件上传实战
curl 是最常用的命令行 HTTP 客户端工具,其 -F 参数专门用于 multipart/form-data 请求。
curl -F 基础语法
curl -F "字段名=值" URL
curl -F "文件字段=@本地文件路径" URL
| 参数形式 | 说明 | 示例 |
|---|---|---|
-F "key=value" |
发送普通文本字段 | -F "prompt=Hello" |
-F "key=@file" |
上传本地文件 | -F "[email protected]" |
-F "key=@file;type=mime" |
指定文件 MIME 类型 | -F "[email protected];type=image/jpeg" |
-F "key=@file;filename=new.jpg" |
自定义上传文件名 | -F "[email protected];filename=upload.jpg" |
curl -F 与其他参数的区别
很多开发者容易混淆 -F、-d 和 -X POST 的用法:
# ❌ 错误: -d 用于 x-www-form-urlencoded,不适合文件上传
curl -X POST -d "[email protected]" https://api.example.com/upload
# ❌ 错误: 手动指定 Content-Type 但使用 -d
curl -X POST -H "Content-Type: multipart/form-data" -d "..." https://api.example.com/upload
# ✅ 正确: 使用 -F 自动设置正确的 Content-Type 和 boundary
curl -F "[email protected]" https://api.example.com/upload
技术说明: 使用
-F时,curl 会自动:
- 将请求方法设为 POST
- 设置
Content-Type: multipart/form-data- 生成唯一的 boundary
- 按照 RFC 标准格式化请求体
Sora 2 API 文件上传实战
Sora 2 是 OpenAI 推出的视频生成模型,支持通过 API 上传参考图片来生成视频。这是 multipart/form-data 的典型应用场景。
Sora 2 图生视频 API 参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
prompt |
string | ✅ | 视频描述文本 |
model |
string | ❌ | 模型选择: sora-2 或 sora-2-pro |
size |
string | ❌ | 分辨率: 1280x720, 720x1280, 1024x1792, 1792x1024 |
seconds |
integer | ❌ | 时长: 4, 8, 12 秒 |
input_reference |
file | ❌ | 参考图片,作为视频首帧 |

Sora 2 模型对比
| 特性 | sora-2 | sora-2-pro |
|---|---|---|
| 生成质量 | 良好 | 卓越 |
| 渲染速度 | 较快 | 较慢 |
| 适用场景 | 快速原型、概念验证 | 生产级输出 |
| 价格 | 标准 | 较高 |
| 可用平台 | API易 apiyi.com, 官方 API | API易 apiyi.com, 官方 API |
Sora 2 文件上传完整示例
以下是使用 curl 调用 Sora 2 API 进行图生视频的完整示例:
curl -X POST "https://api.apiyi.com/v1/videos" \
-H "Authorization: Bearer $APIYI_KEY" \
-H "Content-Type: multipart/form-data" \
-F prompt="She turns around and smiles, then slowly walks out of the frame." \
-F model="sora-2-pro" \
-F size="1280x720" \
-F seconds="8" \
-F input_reference="@sample_720p.jpeg;type=image/jpeg"
命令解析
| 部分 | 说明 |
|---|---|
curl -X POST |
指定 POST 请求方法 |
"https://api.apiyi.com/v1/videos" |
API易 Sora 2 视频生成端点 |
-H "Authorization: Bearer $APIYI_KEY" |
使用环境变量传递 API 密钥 |
-H "Content-Type: multipart/form-data" |
声明内容类型 (curl -F 会自动添加) |
-F prompt="..." |
视频描述提示词 |
-F model="sora-2-pro" |
选择高质量模型 |
-F size="1280x720" |
横屏 720p 分辨率 |
-F seconds="8" |
8 秒时长 |
-F input_reference="@sample_720p.jpeg;type=image/jpeg" |
上传参考图片 |
🚀 快速开始: 推荐使用 API易 apiyi.com 平台快速测试 Sora 2 API。该平台提供开箱即用的 API 接口,无需复杂配置即可完成集成。
图片上传注意事项
使用 Sora 2 API 上传参考图片时需要注意:
| 要求 | 说明 |
|---|---|
| 分辨率匹配 | 图片分辨率必须与目标视频 size 参数匹配 |
| 支持格式 | image/jpeg, image/png, image/webp |
| 文件大小 | 建议不超过 10MB |
| 图片质量 | 清晰、构图完整的图片效果更好 |
Python 实现 multipart/form-data 上传
除了 curl,在实际开发中更常使用编程语言来实现文件上传。以下是 Python 的实现方式。
极简示例
import requests
# 使用 API易 统一接口
url = "https://api.apiyi.com/v1/videos"
headers = {"Authorization": "Bearer YOUR_API_KEY"}
# 准备 multipart 数据
files = {
"input_reference": ("sample.jpeg", open("sample_720p.jpeg", "rb"), "image/jpeg")
}
data = {
"prompt": "She turns around and smiles, then slowly walks out of the frame.",
"model": "sora-2-pro",
"size": "1280x720",
"seconds": "8"
}
response = requests.post(url, headers=headers, data=data, files=files)
print(response.json())
查看完整代码 (含错误处理和轮询)
import requests
import time
import os
class Sora2Client:
"""Sora 2 API 客户端 - 支持 multipart/form-data 文件上传"""
def __init__(self, api_key: str, base_url: str = "https://api.apiyi.com/v1"):
self.api_key = api_key
self.base_url = base_url
self.headers = {"Authorization": f"Bearer {api_key}"}
def create_video(
self,
prompt: str,
model: str = "sora-2",
size: str = "1280x720",
seconds: int = 8,
input_reference: str = None
) -> dict:
"""
创建视频生成任务
Args:
prompt: 视频描述
model: 模型选择 (sora-2 或 sora-2-pro)
size: 分辨率
seconds: 时长 (4, 8, 12)
input_reference: 参考图片路径 (可选)
Returns:
任务信息字典
"""
url = f"{self.base_url}/videos"
data = {
"prompt": prompt,
"model": model,
"size": size,
"seconds": str(seconds)
}
files = None
if input_reference and os.path.exists(input_reference):
# 根据文件扩展名确定 MIME 类型
ext = os.path.splitext(input_reference)[1].lower()
mime_types = {
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".png": "image/png",
".webp": "image/webp"
}
mime_type = mime_types.get(ext, "application/octet-stream")
files = {
"input_reference": (
os.path.basename(input_reference),
open(input_reference, "rb"),
mime_type
)
}
try:
response = requests.post(
url,
headers=self.headers,
data=data,
files=files,
timeout=30
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
return {"error": str(e)}
finally:
if files and "input_reference" in files:
files["input_reference"][1].close()
def get_video_status(self, video_id: str) -> dict:
"""查询视频生成状态"""
url = f"{self.base_url}/videos/{video_id}"
response = requests.get(url, headers=self.headers, timeout=30)
return response.json()
def wait_for_completion(self, video_id: str, poll_interval: int = 10) -> dict:
"""轮询等待视频生成完成"""
while True:
status = self.get_video_status(video_id)
if status.get("status") in ["completed", "failed"]:
return status
print(f"Status: {status.get('status')}... waiting {poll_interval}s")
time.sleep(poll_interval)
# 使用示例
if __name__ == "__main__":
client = Sora2Client(api_key=os.getenv("APIYI_KEY"))
# 创建图生视频任务
result = client.create_video(
prompt="She turns around and smiles, then slowly walks out of the frame.",
model="sora-2-pro",
size="1280x720",
seconds=8,
input_reference="sample_720p.jpeg"
)
if "id" in result:
print(f"Task created: {result['id']}")
final_result = client.wait_for_completion(result["id"])
print(f"Video URL: {final_result.get('video_url')}")
else:
print(f"Error: {result}")
建议: 通过 API易 apiyi.com 获取免费测试额度,快速验证图生视频功能。
requests 库的 multipart 处理
Python requests 库处理 multipart/form-data 的关键点:
| 参数 | 用途 | 说明 |
|---|---|---|
data |
普通表单字段 | 字典格式: {"key": "value"} |
files |
文件字段 | 元组格式: {"name": (filename, file_obj, content_type)} |
⚠️ 注意: 同时使用
data和files参数时,requests 会自动设置正确的Content-Type和 boundary,无需手动指定。
JavaScript/Node.js 实现方案
浏览器环境 (FormData API)
const formData = new FormData();
formData.append('prompt', 'She turns around and smiles');
formData.append('model', 'sora-2-pro');
formData.append('size', '1280x720');
formData.append('seconds', '8');
formData.append('input_reference', fileInput.files[0]);
fetch('https://api.apiyi.com/v1/videos', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY'
// 注意: 不要手动设置 Content-Type
},
body: formData
})
.then(response => response.json())
.then(data => console.log(data));
Node.js 环境
const FormData = require('form-data');
const fs = require('fs');
const axios = require('axios');
const form = new FormData();
form.append('prompt', 'She turns around and smiles');
form.append('model', 'sora-2-pro');
form.append('size', '1280x720');
form.append('seconds', '8');
form.append('input_reference', fs.createReadStream('sample_720p.jpeg'), {
contentType: 'image/jpeg'
});
axios.post('https://api.apiyi.com/v1/videos', form, {
headers: {
...form.getHeaders(),
'Authorization': 'Bearer YOUR_API_KEY'
}
})
.then(response => console.log(response.data));
💡 关键提示: 在浏览器中使用 FormData 时,不要手动设置
Content-Typeheader。浏览器会自动添加正确的 boundary 参数。
multipart/form-data 常见问题排查
上传失败常见原因
| 问题 | 症状 | 解决方案 |
|---|---|---|
| boundary 缺失 | 服务器返回 400 | 不要手动设置 Content-Type,让工具自动生成 |
| MIME 类型错误 | 文件被拒绝 | 使用 ;type=image/jpeg 明确指定 |
| 文件路径错误 | 找不到文件 | 确保 @ 后的路径正确,支持相对/绝对路径 |
| 分辨率不匹配 | Sora API 报错 | 图片分辨率必须与 size 参数匹配 |
| 文件过大 | 超时或被拒绝 | 压缩图片或分片上传 |
调试技巧
使用 curl 的 -v 参数查看完整请求:
curl -v -F "[email protected]" https://api.example.com/upload
这会显示:
- 请求头 (包括自动生成的 Content-Type 和 boundary)
- 请求体结构
- 服务器响应
常见问题
Q1: multipart/form-data 和 Base64 编码哪个更好?
multipart/form-data 更适合文件上传。Base64 编码会将文件体积增大约 33%,增加网络传输时间和服务器处理负担。multipart/form-data 直接传输二进制数据,效率更高。
不过在某些场景下 (如 WebSocket、单字段 JSON API),Base64 可能是唯一选择。通过 API易 apiyi.com 平台调用 API 时,优先使用 multipart/form-data 方式可获得更好的性能体验。
Q2: 为什么我的 curl -F 上传失败?
常见原因包括:
- 文件路径问题: 确保
@符号后跟正确的文件路径 - 权限问题: 检查文件读取权限
- MIME 类型: 某些 API 要求指定正确的 content-type
建议先通过 API易 apiyi.com 获取测试环境验证请求格式,平台提供详细的错误信息帮助快速定位问题。
Q3: Sora 2 API 支持哪些图片格式?
Sora 2 API 支持以下图片格式用于 input_reference:
- JPEG (
.jpg,.jpeg) – 推荐,压缩率好 - PNG (
.png) – 支持透明通道 - WebP (
.webp) – 现代格式,体积小
图片分辨率必须与目标视频的 size 参数匹配。例如使用 1280x720 分辨率,参考图片也需要是 1280×720。
Q4: 如何处理大文件上传?
对于大文件上传,可以考虑:
- 分片上传: 将文件分成小块依次上传
- 压缩优化: 在保证质量的前提下压缩文件
- 断点续传: 支持上传失败后从断点继续
multipart/form-data 支持流式传输,服务器可以边接收边处理,适合大文件场景。
总结
本文详细介绍了 API 文件上传的核心技术 multipart/form-data:
关键知识点回顾:
| 要点 | 说明 |
|---|---|
| 编码原理 | boundary 分隔多部分数据,每部分独立 Content-Type |
| curl -F 命令 | -F "key=value" 发送文本,-F "key=@file" 上传文件 |
| Sora 2 实战 | input_reference 参数上传参考图片,分辨率需匹配 |
| 多语言实现 | Python requests / JavaScript FormData |
| 调试技巧 | 使用 curl -v 查看完整请求 |
掌握 multipart/form-data 是进行 AI API 开发的基础能力。无论是 Sora 2 视频生成、GPT-4 Vision 图像理解,还是其他需要文件上传的 API,核心原理都是相通的。
推荐通过 API易 apiyi.com 快速验证文件上传功能,体验统一的 API 接口和详尽的技术支持。
作者: APIYI Team | 专注 AI 大模型 API 技术分享
技术交流: 访问 apiyi.com 获取更多 API 开发资源
参考资料
-
RFC 2388: multipart/form-data 标准规范
- 链接:
tools.ietf.org/html/rfc2388
- 链接:
-
curl 官方文档: Multipart Formposts
- 链接:
everything.curl.dev/http/post/multipart
- 链接:
-
MDN Web Docs: Using FormData Objects
- 链接:
developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest_API/Using_FormData_Objects
- 链接:
-
OpenAI Sora API 文档: Video Generation Guide
- 链接:
platform.openai.com/docs/guides/video-generation
- 链接:
