在使用Stability AI提供的SDXL模型接口时,如果需要以图生图或者上传掩码、参考图,就必须采用multipart/form-data的编码方式把图片文件和文本参数一起发往服务器。这种格式和普通的application/json不同,它依靠一个随机生成的boundary把请求体切成多个部分,每一部分都有自己的header和body,从而让二进制图片和字符串字段共存于同一个HTTP请求里。理解这一点,是正确调用接口的前提。

multipart/form-data 的底层结构与SDXL字段要求
从协议层面看,当浏览器或HTTP客户端设置Content-Type: multipart/form-data; boundary=xxxx时,请求正文会被boundary分割成若干段。每一段以两个连字符加boundary开头,接着是Content-Disposition头,里面写明字段名name以及如果是文件还需filename和Content-Type。SDXL的图像接口通常要求把图片放在名为image的字段,而采样步数、提示词等放在prompt、steps等字段。若字段名不符,API会返回400错误,提示缺少必要参数。
很多开发者习惯用JSON传参,直接把图片转成base64塞进json,但Stability AI的SDXL上传端点明确拒绝application/json,必须使用表单。这是因为大体积图片用base64会让请求膨胀约三分之一,且服务端解析慢。表单方式下,原始字节直接传输,效率更高。我们可以在抓包工具里看到,正确的请求体类似:------boundaryrnContent-Disposition: form-data; name="image"; filename="a.png"rnContent-Type: image/pngrnrn<二进制>rn------boundary--。
还要注意,boundary的值不能出现在文件内容中,客户端库通常会自动生成随机串。如果手动拼装,务必保证每个部分结尾的rn和结束符准确。SDXL接口对steps等数值字段仍期望字符串或数字,但表单会自动以文本发送,后端自行转换。搞清这些细节,才能避免拿到奇怪的解析异常。
Python 后端使用 requests 上传图片到 SDXL
在Python环境,最方便的是用requests库,它会在传入files和data参数时自动构造multipart请求。我们无需手动写boundary,只要把图片以二进制打开,并用元组形式声明文件名与类型。下面示例展示调用SDXL图像到图像端点,上传本地图并指定提示词。
import requests
api_key = "你的API密钥"
url = "https://api.stability.ai/v1/generation/sd-xl-1.0/image-to-image"
with open("input.png", "rb") as f:
files = {
"image": ("input.png", f, "image/png")
}
data = {
"prompt": "make it rainy",
"steps": 30,
"strength": 0.5
}
headers = {
"Authorization": f"Bearer {api_key}",
"Accept": "application/json"
}
resp = requests.post(url, headers=headers, files=files, data=data)
print(resp.status_code)
print(resp.json())
上述代码中,files字典的键image就是SDXL要求的字段名,值元组里包含文件名、文件对象和MIME类型。requests会自动设置Content-Type为multipart/form-data并带上boundary,我们不要自己加这个header,否则可能boundary不匹配。返回结果一般是JSON,里面带生成图的base64或URL。
如果碰到415错误,多半是误把json=data传进去,或者手动覆盖了Content-Type。另外,SDXL某些版本还要求Accept: image/png来直接拿二进制图,这时要按文档调整。用Python做批量上传时,建议用with语句管理文件,防止句柄泄露,并用session复用连接提升吞吐。
JavaScript 前端与Node环境如何组装表单
在浏览器里,可以直接用FormData对象,它天然产生multipart/form-data。把input拿到的File对象append进去即可,不用关心boundary。以下片段演示从文件输入框取图并发请求。
const input = document.querySelector('input[type="file"]');
const file = input.files[0];
const fd = new FormData();
fd.append("image", file, "input.png");
fd.append("prompt", "turn to sketch");
fd.append("steps", "30");
fetch("https://api.stability.ai/v1/generation/sd-xl-1.0/image-to-image", {
method: "POST",
headers: {
"Authorization": "Bearer 你的API密钥"
},
body: fd
}).then(r => r.json()).then(console.log);
注意这里没有设置Content-Type,因为浏览器会在发送FormData时自动补上带boundary的multipart头。如果手动设成multipart/form-data却不带boundary,请求会失败。Node.js服务端若用axios或node-fetch,也可构造FormData(需form-data包),逻辑类似。前端直连API有跨域限制,生产环境一般让自家后端转发。
对比前后端方案,浏览器FormData最省心,但暴露密钥风险大;Python后端适合服务化调用。无论哪种,核心都是字段名匹配SDXL文档、图片为二进制流、不手动错改Content-Type。只要抓住multipart分段本质,调试时用日志打印出请求体前几百字节,就能迅速定位boundary或字段遗漏问题,稳定实现图片上传与生成。
Stability_AI_APISDXLmultipart_form_data修改时间:2026-08-14 05:54:27