如何在Node.js中将文件作为API请求的Payload发送?
修复文件上传到OpenAI API的问题
你的代码存在三个核心问题,导致文件上传失败:
- 不该用
JSON.stringify()包裹FormData对象,这会把FormData转成空对象{},完全丢失文件数据 - 手动指定
Content-Type: multipart/form-data是错误的,浏览器会自动为multipart请求添加带boundary的Content-Type头,手动设置会缺失boundary,服务器无法解析请求 purpose字段需要添加到FormData中,而不是放在无效的JSON结构里
修正后的完整代码
function UploadFileInput(props){ const [selectedFile, setSelectedFile] = useState(); const [isSelected, setIsSelected] = useState(false); const apiKey = props.api; // 上传文件到OpenAI的函数 async function uploadFile(api, formData){ const URL = "https://api.openai.com/v1/files"; try{ const response = await fetch(URL,{ method: 'POST', headers: { 'Authorization': `Bearer ${api}` // 移除手动设置的Content-Type,让浏览器自动处理 }, body: formData // 直接传递FormData对象,不要用JSON.stringify }); // 处理响应 if(response.ok){ const data = await response.json(); console.log("API响应:", data); }else{ const errorData = await response.json(); console.log("错误状态码:", response.status, "错误信息:", errorData); } } catch(error){ console.log("API请求出错"); console.error(error); } } const handleClick = ()=>{ if(!isSelected){ console.log("未选择文件"); return; } // 向FormData中添加文件和purpose字段 const formData = new FormData(); formData.append('file', selectedFile); formData.append('purpose', "fine-tune"); // 把purpose加入FormData uploadFile(apiKey, formData); } function changeHandler(e){ setSelectedFile(e.target.files[0]); setIsSelected(true); } return ( <> <input type="file" name="file" onChange={changeHandler} className="custom-file-input"/> <Button variant="contained" onClick={handleClick}>Upload File</Button> {isSelected ? <p>文件名: {selectedFile.name}</p> : null} </> ) }
关键修改说明
- FormData处理:在
handleClick中把purpose字段直接添加到FormData里,确保API能接收到所有必填参数 - 请求体调整:
uploadFile函数中直接将FormData作为body参数传递,移除JSON.stringify(),保留文件的二进制数据 - 请求头调整:删除手动设置的
Content-Type: multipart/form-data,浏览器会自动生成包含正确boundary的请求头,确保服务器能正确解析multipart格式的数据 - 响应处理优化:用
response.ok判断请求成功(覆盖200-299状态码),同时解析错误响应的JSON数据,方便排查问题
内容的提问来源于stack exchange,提问作者hackerfish
相关产品推荐
相关产品推荐

