命令行调用还好好的,网页一发请求却蹦出 CORS 报错?先别让模型背锅,可能是浏览器门口换了规矩。vLLM 0.32.0 把默认允许的跨来源网页列表从 * 改成了空列表。你的网页若直接请求另一来源的自建 vLLM,升级后就要显式允许可信网页来源;后端脚本直连 API,不受浏览器这道 CORS 检查约束。
这项变化写在 vLLM 0.32.0 发布说明和合并的 PR #61009 中。它改变的是浏览器能否读取跨来源响应,不代表模型推理、API 鉴权或星桥网关也发生了同样的变化。

图:用门禁作比喻说明浏览器来源限制;AI 生成的情境图,不是实际界面或故障截图。
第一处:请求是谁发的?
打开浏览器开发者工具的 Network 和 Console,先看请求来自网页,还是来自你的后端服务。
- 网页
https://app.example.com直接请求另一域名或端口的 vLLM,并看到 CORS、Access-Control-Allow-Origin或OPTIONS预检错误:继续往下查。 curl、Python 服务或后端任务请求 vLLM 正常,只有网页失败:更像浏览器跨来源问题,但仍要核对具体响应。- 请求返回 401、429 或模型加载错误:先按鉴权、额度/限流或服务日志排查,别啥锅都让 CORS 背。
协议、主机和端口只要有一个不同,就可能是跨来源。http://app.example.com 与 https://app.example.com 也不是同一个来源。
第二处:预检和响应到底缺什么?
在 Network 中选中失败请求,记录网页的 Origin,再看 OPTIONS 预检或正式响应里有没有对应的 Access-Control-Allow-Origin。PR #61009 说明:默认配置下,外部来源不会得到允许读取响应的该响应头,JSON 请求的预检也不会获准。
如果错误发生在反向代理后面,还要确认请求实际到达的是哪个服务、哪个版本。光看网页上一个红字,不足以断定一定是 vLLM 默认值造成的。

图:CORS 排查知识结构图。它概括请求和响应的判断路径,不是某次部署的实测截图。
第三处:只放行你自己的网页
你能控制 vLLM 启动参数时,把真实的网页来源写进 --allowed-origins。下面是配置格式示例,未在你的部署上实测;YOUR_MODEL 和域名都要换成自己的值:
vllm serve YOUR_MODEL --allowed-origins '["https://app.example.com"]'
重启或重新部署后,再用同一个网页重试:检查预检是否通过、正式响应是否能被页面读取。若前面有反向代理,也核对它有没有拦截 OPTIONS 或改写响应头。
别为了省事直接改回 *。 这会重新放开任意来源网页读取响应的范围。更要紧的是,CORS 不是 API 鉴权:即使浏览器读不到响应,也不能据此认为接口不会被请求。公网暴露的服务仍需单独做好密钥、权限与访问控制。
如果网页不必直连模型,可以让网页请求自己的后端,再由后端调用 vLLM。这样密钥留在服务端,也避开浏览器直接跨来源调用模型服务的场景;但后端本身仍需鉴权和防滥用。
三步收工:确认请求确实来自网页;对照 Origin、预检和响应头;只允许可信来源并复查。没升级到 0.32.0、没有网页直连,或报错其实是 401/429 的,别按这篇硬改配置。
星桥 API 网关由我们运营。若你需要统一的模型 API 接入入口,可在公众号菜单「接入文档」查看;这不等于星桥能替你修复自建 vLLM 的跨域配置。
资料:vLLM 0.32.0 官方发布说明、合并 PR #61009;核对于 2026-10-27。本文未在读者的部署上实测,具体结果还取决于服务版本、反向代理和浏览器请求。
