那些年踩过的API坑:我是如何从密钥泄露到建立完整代理方案的
不知道你有没有过这样的经历:兴冲冲地调用第三方AI接口,结果浏览器控制台一片红,密钥错误、跨域拦截、格式不对,各种问题接踵而至。
别担心,今天想和你聊聊我在语音合成和视觉理解这两个能力接入过程中走过的弯路,希望能帮你绕开那些我曾经掉进去的坑。
一个冲动决定的代价
那会儿刚接触多模态业务,想着快点看到效果,直接在Vue组件里写了AppID和AccessToken。结果第二天收到欠费通知——有人用我的密钥跑了大量请求。教训很深刻:前端代码就是透明的,任何敏感信息一旦进去,就等于向全世界公开。
浏览器不能做的事
浏览器的同源策略和CORS机制决定了它不能直接访问第三方API,更不能安全地存储密钥。本地server.js扮演的BFF角色就像一个可信赖的管家,帮你保管钥匙,你只需要告诉它想做什么,它会替你完成。
两个厂商,两种鉴权方式
火山引擎TTS用的是Authorization:Bearer;token这个特殊格式,分号不是空格,官方文档里写得清清楚楚但很容易被忽略。Moonshot则是标准的Bearer空格token。如果你同时接两个厂商,这个细微差异会让你的Header拼装逻辑完全不同。写进BFF统一处理,前端就省心了。
从最小可运行开始
不要一上来就写完整的代理服务和华丽的UI。先用curl命令验证上游是否可达,密钥是否有效,路径是否正确。等这条路通了,再加一层本机代理,最后才是前端界面。分步骤验证的好处是:出了问题一定能定位到具体在哪一层。
图片base64的那些事儿
视觉模型接收的图片需要转成base64塞进DataURL。这个字符串有多大?一张普通照片转完通常是几MB起步。浏览器POST这么大的body,很容易触发网关超时或大小限制。产品化的时候,要么引导用户压缩图片,要么直接传对象存储的URL。本文的demo为了简单起见,先文档化了这个约束。
单页和BFF怎么分工
有个清晰的职责划分能省掉很多沟通成本。单页负责:把用户的输入变成JSON、把响应解析成UI状态、展示错误信息。BFF负责:读环境变量拼Header、转发到正确的上游、把上游响应原样返回。前端永远不需要知道真实的API地址和密钥是什么。
给新手的几点忠告
环境变量改了要重启服务,这个很多人都知道但容易忽略。流式输出听起来很美好但复杂度会飙升,非流式跑通再考虑进阶。文档要仔细看,特别是那些容易出错的格式细节,有时候一个分号就能卡你半天。
技术路上坑很多,但每踩过一个就会更稳一点。希望今天的分享能让你少走些弯路。
