在上一篇文章中,我们搭建了前端界面,实现了图像上传、参数配置与预览功能。今天,我们将正式接入 Coze 平台的工作流(Workflow) ,完成一个完整的 AI 冰球头像生成器!但在开发过程中,你可能会遇到各种网络错误、Token 失效等问题。本文将深入讲解如何正确调用 Coze API、处理常见 HTTP 错误,并管理 Token 生命周期。
🌐 一、HTTP 网络请求基础:401、404、500 是什么?
在调用远程 API(如 Coze 的文件上传或工作流执行接口)时,如果返回非 200 状态码,说明请求出现了问题。以下是三个最常见错误的含义:
| 状态码 | 名称 | 含义 |
|---|---|---|
| 401 | Unauthorized | 未授权:缺少有效身份凭证(如 Token 错误、过期、未提供)。 |
| 404 | Not Found | 资源不存在:请求的 URL 路径错误,或该接口已被移除/拼写错误。 |
| 500 | Internal Server Error | 服务器内部错误:Coze 后端出错(可能是工作流配置错误、服务异常等)。 |
✅ 关键点:这些状态码由 服务器返回,但
fetch默认不会抛出异常(即使 500 也会 resolve),所以必须手动检查response.ok或解析返回的 JSON 中的code字段。
💡 答疑解惑:为什么 fetch 没报错,但我的请求失败了?
Q:我用了
await fetch(...),但没看到错误,图片却没生成?
A:因为 fetch 只在网络层失败(如断网)时 reject,而 HTTP 4xx/5xx 仍算“成功响应” 。你需要主动检查:
const res = await fetch(url, options);
if (!res.ok) {
console.error('HTTP Error:', res.status);
}
// 或者像你代码中那样,检查 Coze 返回的 { code: 0 } 结构
思考题:如果 Coze 返回
{ code: 401, msg: "Invalid token" },但 HTTP 状态码是 200,这合理吗?
提示:很多 API(包括 Coze)使用 业务状态码(code) 而非 HTTP 状态码来表示逻辑错误,这是为了统一错误格式。
🔑 二、Coze PAT Token 机制与过期问题
const patToken = import.meta.env.VITE_PAT_TOKEN;
这是一个 Personal Access Token (PAT) ,用于身份认证。
⚠️ Token 会过期吗?
会! Coze 的 PAT 默认有有效期(通常为 30 天或更短),过期后所有带该 Token 的请求都会返回 401 Unauthorized。
✅ 正确做法:
- 不要硬编码 Token:你已通过
.env文件管理(VITE_PAT_TOKEN),很好 👍。 - 定期更新 Token:在 Coze 控制台重新生成,并更新
.env。 - 前端无法自动刷新 Token:PAT 是长期凭证,不像 OAuth 有 refresh_token。因此需人工维护。
- 切勿泄露 Token:虽然
VITE_前缀确保只在构建时注入(不会打包到客户端),但仍要避免提交到 Git!
💡 答疑解惑:为什么我的 Token 明明刚生成,却还是 401?
Q:我确认
.env里有VITE_PAT_TOKEN=xxx,重启了 dev server,但还是 401?
可能原因:
.env文件未放在项目根目录- 变量名拼写错误(必须是
VITE_PAT_TOKEN,Vite 只暴露以VITE_开头的变量) - Token 在 Coze 控制台被禁用或删除
- 请求头格式错误:应为
'Authorization': 'Bearer xxx'(注意Bearer后有空格)
验证方法:在
console.log(patToken)查看是否为undefined。如果是,说明环境变量未加载成功。
思考题:如果多人协作开发,每个人都用自己的 PAT,如何避免冲突?
建议:每人本地维护自己的.env.local(加入.gitignore),团队共享.env.example模板。
📤 三、文件上传:FormData 与 Coze 文件接口
你使用了标准的 HTML5 文件上传流程:
const formdata = new FormData();
formdata.append('file', input.files[0]);
const res = await fetch(uploadUrl, {
method: 'POST',
headers: { 'Authorization': `Bearer ${patToken}` },
body: formdata
});
✅ 关键细节:
- 无需设置
Content-Type:浏览器会自动设置为multipart/form-data; boundary=... - Coze 要求字段名为
file:你已正确使用formdata.append('file', ...)。 - 返回结构:成功时
ret.code === 0,文件 ID 在ret.data.id。
💡 答疑解惑:为什么上传成功了,但工作流说“文件不存在”?
Q:
uploadFile()返回了 file_id,但调用 workflow 时提示文件无效?
可能原因:
- 文件 ID 传递错误(比如字符串 vs 对象)
- 工作流中的“文件输入节点”未正确绑定参数
- 文件上传后未等待 Coze 完成处理(极少见)
你的代码是安全的:
picture: JSON.stringify({ file_id }) // ✅ 正确传递
但注意:某些 Coze 工作流要求直接传 file_id 字符串,而非对象。请查阅你所用工作流的文档!
思考题:如果用户快速点击两次“生成”,会不会上传两个文件?如何防止重复请求?
进阶方案:在generate函数开头加锁(if (status.value) return;)。
⚙️ 四、调用 Coze 工作流:参数传递与结果解析
你调用工作流的核心代码:
const parameters = {
picture: JSON.stringify({ file_id }),
uniform_number: uniform_number.value,
// ...其他参数
};
const res = await fetch(workflowUrl, {
method: 'POST',
headers: {
'Authorization': `Bearer ${patToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ workflow_id, parameters })
});
✅ 注意事项:
workflow_id必须正确:请确认这是你工作流的 真实 ID(可在 Coze 控制台复制)。- 参数名必须匹配工作流定义:比如工作流里叫
jersey_color,你却传uniform_color,就会失败。 picture字段的特殊性:Coze 要求文件以{ file_id: "xxx" }对象形式传入,并 JSON.stringify 成字符串 —— 这是你代码中最容易出错的地方!
为什么需要
JSON.stringify?
因为 Coze 工作流的“变量”类型可能是 字符串,而你实际想传一个对象。所以先转成字符串,工作流内部再 parse。
💡 答疑解惑:为什么工作流返回成功,但 imgUrl 是空的?
Q:
ret.code === 0,但data.data是空字符串或 undefined?
排查步骤:
console.log(ret)看完整响应结构- 确认工作流 最后一个节点是否输出了图片 URL
- 检查工作流是否配置了 “返回结果” 节点
- 有些工作流返回的是 Base64 或 文件对象,而非 URL
你的代码假设:
data.data就是图片 URL。但实际可能需要:
// 例如 Coze 返回 { image_url: "https://..." }
imgUrl.value = data.image_url;
务必根据你工作流的实际输出结构调整!
思考题:如果工作流执行耗时 30 秒,用户会不会以为卡死了?如何优化体验?
答案:可考虑轮询、WebSocket 或使用 Coze 的异步回调机制(如有)。
🧩 五、整体数据流与状态管理
你的状态设计非常清晰:
const status = ref('');
// '' → "图片上传中..." → "图片上传成功,正在生成..." → (成功清空 / 失败显示错误)
const imgUrl = ref(''); // 最终生成的图片
这种 状态驱动 UI 的方式是 Vue3 Composition API 的最佳实践。
💡 答疑解惑:为什么生成失败后,再次点击“生成”没反应?
Q:第一次失败后,
status显示错误信息,但第二次点击按钮无变化?
原因:我的 generate 函数开头没有重置状态!
const generate = async () => {
status.value = "图片上传中..."; // ✅ 这会覆盖之前的错误
// ...
}
但如果想更健壮,可加:
if (!uploadImage.value?.files?.[0]) {
alert('请先选择图片');
return;
}
思考题:如果用户切换了“风格”但没换图,能否复用上次上传的 file_id?
优化方向:缓存 file_id,避免重复上传相同图片。
✅ 总结:打造健壮的 AI 应用前端
通过本次接入 Coze 工作流,我们掌握了:
- 🛡️ HTTP 错误码的含义与处理策略
- 🔐 PAT Token 的安全使用与生命周期管理
- 📤 FormData 文件上传的标准流程
- ⚙️ 工作流参数的精确传递与结果解析
- 🧠 状态驱动的用户体验设计
🚀 下一步建议
- 添加 loading 动画:让用户感知“正在生成”
- 支持多图历史记录:保存生成结果
- 错误重试机制:对 500 错误自动重试 1~2 次
- 日志监控:记录
patToken是否泄露(通过 Network 面板检查)
记住:AI 应用 = 前端体验 × 后端能力 × 错误容忍度。你已经走出了坚实的一步!💪
✨ Happy Coding, and may your hockey avatars always score goals! 🏒