纯前端调用大模型真的安全吗?我踩过的坑比示例代码多得多
前言:示例代码很美好,真实项目很残酷
这两年大模型 API 越来越好用,官方文档、示例代码也越来越“友好”,复制一段 fetch,在浏览器里就能跑起来一个 AI 对话页面,看起来好像一切都很简单。但真正把这种“纯前端调用大模型”的方案用到项目里,我踩过的坑比示例代码多得多。
尤其是当你开始关心 安全、稳定性、成本和真实用户行为 时,就会发现:示例代码只解决了“能跑”,却完全没覆盖“能上线”。
这篇文章不讨论对错,只分享我在实际项目里踩过的坑,以及后来总结出的经验。
一、Token 暴露:这是最基础、也是最致命的问题
几乎所有“纯前端直调模型 API”的方案,绕不开一个问题:API Key 放哪?
答案很残酷:只要在前端,就一定会被拿走。
无论你是:
- 写在 JS 里
- 放在 env 再打包
- 简单混淆一下
- 放在请求 header 里
只要请求是从浏览器发出去的,Token 就是明文可见的。浏览器 Network 面板、代理工具、抓包工具都能轻松拿到。
我一开始也抱着“只是内部工具,应该没事”的侥幸心理,结果没多久就发现额度异常增长。那一刻才真正意识到:
前端环境天生不可信。
后来我的原则就变成了一条铁律:任何长期有效、可计费的密钥,都不允许出现在前端。
二、CORS 与跨域:你以为是配置问题,其实是架构问题
很多模型 API 默认是不允许浏览器直接跨域调用的,这一点其实是好事。它在某种程度上是在“阻止你犯错”。
但也有人会选择通过:
- 自建 CORS 代理
- 用 Cloudflare Worker / Edge Function
- 或者随便找一个开放代理来“绕过跨域”。
问题在于,一旦你引入了这些中间层:你是不是在帮别人转发模型请求?有没有做来源校验?有没有限制调用频率?有没有 Token 隔离?
我见过不止一次:一个“临时 CORS 代理”,最后变成了公开模型中转站。
跨域问题本质不是技术问题,而是一个信号:浏览器不适合直接成为模型调用的源头。
三、流式解析:前端最容易被忽略的隐形坑
流式响应在 Demo 里看起来很顺,但放到真实环境里,问题就开始冒出来了。
我遇到过的情况包括:
- 流里夹杂不可见字符,JSON 解析直接卡死
- 网络抖动导致 chunk 截断,前端一直在等
- 某些代理层把 chunk 合并,流式退化成“假流”
不同模型返回的流格式略有差异,前端逻辑写得一团糟
最糟糕的是:前端一旦流解析失败,用户看到的就是“模型卡住了”。但实际上模型早就返回了,只是前端没处理好。
后来我总结出一个经验:前端不应该直接面对复杂、不稳定的模型流。流式解析、异常兜底、格式统一,这些都更适合放在一个可控的中间层。
四、Token 消耗与上下文膨胀:前端很容易“越用越慢”
纯前端方案里,另一个常见问题是:
-
上下文完全失控。
-
常见写法是:
点击查看代码
messages.push(userInput)
messages.push(modelResponse)
看起来没问题,但结果就是:每一轮都在把历史完整塞回去,prompt 越来越长 token 消耗指数级增长。推理速度明显下降
前端开发者往往感知不到 token 的真实成本,也很难在浏览器里做复杂的上下文裁剪、摘要、缓存。
最终表现出来的就是一句话:“模型怎么越用越慢?”
五、前端安全:问题从来不只在 Token
即便你侥幸解决了 Token 问题,前端直调模型还有很多隐性风险:
- Prompt 模板暴露,业务逻辑被一眼看穿
- 用户可以随意构造输入,绕过限制
- 恶意用户可以批量发请求消耗资源
- 很难做统一限流和风控
这些问题在 Demo 阶段几乎看不出来,但一旦有真实用户,就会立刻放大。
写在最后
回头看我踩过的这些坑,其实问题不在“能不能纯前端调用大模型”,而在于:浏览器并不是一个安全、稳定、可控的推理入口。示例代码解决的是“快速体验”,而不是“长期运行”。一旦你关心安全、成本、稳定性和可维护性,就会自然地把模型调用往后移,把前端当成一个干净的输入输出层。
在实际工程里,很多团队最终都会选择通过后端或统一的中间层来调用模型 API,有些也会使用像 wavespeed、GPT Proto 这样整合多家模型的 API 接口,减少前端直接面对不同供应商细节的复杂度。但无论选哪种方式,有一点是共通的:
前端越“轻”,系统反而越安全、越稳定。
希望这篇踩坑总结,能帮你少走几步弯路。
浙公网安备 33010602011771号