Ollama、LM Studio 与任意 OpenAI 兼容端点

让 SideBoo 谷歌浏览器插件接上 Ollama、LM Studio、vLLM 或公司内网网关 —— 包括那条能消掉 403 的 OLLAMA_ORIGINS 设置。

9 分钟阅读 · 最后更新 2026-08-27

修掉 Ollama 的 403 / OLLAMA_ORIGINS 报错

Ollama 对浏览器扩展回 403,是因为它会校验 Origin 请求头,而默认只信任本机的网页来源。浏览器扩展没有这种来源:它的请求带的是 Origin: chrome-extension://<扩展 ID>,不在那份名单里。把 OLLAMA_ORIGINS 这个环境变量设成允许扩展来源,再重启 Ollama,403 就没了。

SideBoo 需要的值是 chrome-extension://*。具体怎么设取决于 Ollama 是怎么启动的,而且环境变量必须在 Ollama 启动之前就位——这正是很多人设了变量、再看还是 403、于是断定「没用」的原因。

各平台的 OLLAMA_ORIGINS 设法
# macOS —— 菜单栏应用的环境变量来自 launchd
launchctl setenv OLLAMA_ORIGINS "chrome-extension://*"
# 然后从菜单栏退出 Ollama,再重新打开

# Linux —— Ollama 跑在 systemd 单元里
sudo systemctl edit ollama.service
#   [Service]
#   Environment="OLLAMA_ORIGINS=chrome-extension://*"
sudo systemctl daemon-reload
sudo systemctl restart ollama

# Linux / macOS —— 或者干脆前台跑一次
OLLAMA_ORIGINS="chrome-extension://*" ollama serve

Windows 上,Ollama 读的是你账号的环境变量,而不是你当前那个终端里的。先从系统托盘退出 Ollama,在开始菜单里搜「编辑账户的环境变量」,新建一个名为 OLLAMA_ORIGINS、值为 chrome-extension://* 的用户变量,再重新启动 Ollama。在 shell 里用 set 或 $env: 设的变量只对那个 shell 拉起的进程有效,对托盘里的应用毫无作用。

LM Studio 有同一道关卡,只是换了个名字:它的本地服务在你打开 CORS 之前,一样拒绝跨源请求。开关和服务器的其它控制项放在一起——较新的版本里在 Developer 标签页,挨着端口输入框和启动/停止按钮。打开它,重启服务,再点一次「测试服务」。

什么时候需要自定义端点

只要你的模型服务实现了 OpenAI 的 /v1/chat/completions 协议,就能接进 SideBoo。在设置页打开「AI 助手」,点「添加提供商」,选弹窗底部那张虚线卡片「自定义 OpenAI 兼容服务」。自定义服务要你填三样:名称、API 地址、API Key。

常见的几类场景:

  • 本地模型:Ollama、LM Studio、llama.cpp 的 server 模式;
  • 自建推理服务:vLLM、SGLang、TGI;
  • 聚合路由:OpenRouter 等把多家模型收敛到一个地址的服务;
  • 公司内网网关:统一鉴权、审计和限流的企业代理。

本机服务通常不校验凭据,所以 API Key 那一栏可以留空:只要 SideBoo 看到地址指向 localhost 或 127.0.0.1,就不再要求填 Key。这两个主机名也是仅有的两个允许走明文 http 的地址——远程服务必须是 https,而 IPv6 字面量(例如 http://[::1]:11434/v1)会被直接拒绝。

接口地址怎么填

地址填到 /v1 为止,不要带 /chat/completions——SideBoo 会自己拼后面的路径。多填一层会得到 404,而不是更明确的报错。

常见的接口地址写法
# 本地 Ollama
http://localhost:11434/v1

# 本地 LM Studio
http://localhost:1234/v1

# OpenRouter
https://openrouter.ai/api/v1

# 自建 vLLM
https://llm.internal.example.com/v1

先用 curl 验证一次

在填进 SideBoo 之前,先确认这个地址和 Key 本身是通的。这一步能把「服务端问题」和「扩展问题」彻底分开:

验证端点是否可用
curl https://your-endpoint.example.com/v1/chat/completions \
  -H "Authorization: Bearer $YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "your-model-name",
    "messages": [{ "role": "user", "content": "ping" }],
    "max_tokens": 8
  }'

期望看到 200,响应体里有 choices[0].message.content。如果这一步就失败,问题在服务商或你的网络,改扩展设置没有意义。

跨源请求与 CORS

这是自建端点最容易踩的坑:curl 完全正常,扩展里却一直失败。curl 根本不发 Origin 请求头,所以它永远不会触发浏览器那道校验。浏览器扩展发出的是跨源请求,来源为 chrome-extension://<扩展 ID>,服务端必须显式允许它。

服务端至少要在预检(OPTIONS)和实际响应里带上:

  • Access-Control-Allow-Origin:回显请求的 Origin,或者设为 *;
  • Access-Control-Allow-Headers:至少包含 authorization 和 content-type;
  • Access-Control-Allow-Methods:包含 POST 和 OPTIONS。
Nginx 反向代理的最小配置
location /v1/ {
  if ($request_method = OPTIONS) {
    add_header Access-Control-Allow-Origin  $http_origin always;
    add_header Access-Control-Allow-Headers "authorization, content-type" always;
    add_header Access-Control-Allow-Methods "POST, OPTIONS" always;
    add_header Access-Control-Max-Age       86400 always;
    return 204;
  }

  add_header Access-Control-Allow-Origin $http_origin always;
  proxy_pass http://127.0.0.1:8000;
}

本地模型的额外注意事项

本地模型便宜又私密,同时也是最容易让人失望的那种配置。它有三个失败方式和网络毫无关系——问题出在模型本身撑不起 SideBoo 要它做的事:

  • 「问 AI」整理标签页时,需要模型稳定地吐出合法 JSON。参数量太小的模型经常给出无法解析的结果;7B 往下,做摘要还行,分组就别指望了。
  • 上下文长度至少留到 8K,60 个标签页的标题加提示词很容易超过 4K 的窗口。
  • 冷模型是在第一次请求时才加载的,所以第一次「测试服务」可能超时、第二次却成功。下结论之前先跑两遍。

模型名怎么填

模型名要和服务端的标识符完全一致,包括大小写、日期后缀和厂商前缀。聚合路由几乎总是需要前缀:

服务模型名示例
Ollamallama3.1:8b
vLLM启动时 --served-model-name 指定的那个名字
OpenRouteranthropic/claude-sonnet-5
内网网关由网关自己定义,通常列在它的 /v1/models 里

拿不准时,直接请求端点的 /v1/models,返回列表里的 id 就是可以填的值。如果这个端点压根没有 /v1/models,「测试服务」会报「发现 0 个模型」;点「手动添加模型 ID」自己把名字打进去即可,对话不受影响。

怎么看到真正的错误

设置页里的提示是概括过的。要看服务端返回的原文,打开扩展的后台控制台:

  1. 打开 chrome://extensions 右上角把「开发者模式」打开。
  2. 点开 SideBoo 卡片上的 service worker 会弹出一个只属于扩展后台的 DevTools 窗口。
  3. 切到 Network 标签再触发一次 AI 操作 找到发往你端点的那条请求,Response 里就是服务端返回的完整错误体。

出问题时对照这张表

下面每一行都是一个真实的状态码或报错,对上的是真正造成它的那一件事。照现象找,别照猜想找——这一页上最常见的一个下午,就浪费在为一个根本与 Key 无关的问题反复重新生成 API Key。

现象怎么处理
测试服务提示 401Key 复制时多了空格或被截断,或者 Key 已在控制台里撤销。重新生成一个再粘贴。
本机 Ollama 测试服务提示 403来源校验。按本页开头设置 OLLAMA_ORIGINS 并重启 Ollama。
测试服务提示 429账户没有余额或触发了速率限制。先去服务商控制台确认额度,再等一分钟重试。
测试服务提示 404接口地址多带了 /chat/completions,或者少了 /v1。按上面「接口地址怎么填」重填一次。
连接正常但发现 0 个模型该服务没实现 /models。手动把模型 ID 填进去,对话照常可用。
提示模型不存在模型名要和服务端标识符完全一致。请求 /v1/models 查一下真实的 id。
curl 正常但扩展里失败几乎一定是 CORS 或来源校验。看后台控制台里的网络错误,按上面配置服务端。
整理结果分组很奇怪标签页标题信息太少时模型只能猜。换成能力更强的模型,或者先手动关掉一批空白页再问。
整理标签页时报解析失败模型没有返回合法 JSON,常见于小参数量的本地模型。换更大的模型,或改用云端服务商。
「问 AI」显示「未配置模型」没有一家服务到达「已就绪」。回设置页点「测试服务」,并至少勾选一个模型。

常见问题

为什么 Ollama 对浏览器扩展回 403?

因为 Ollama 会校验 Origin 请求头,默认只接受 http://localhost 这类本机网页来源。Chrome 扩展发出的是 Origin: chrome-extension://<扩展 ID>,不在那份名单里,所以请求在到达模型之前就被拒了。同一个请求用 curl 发就成功,是因为 curl 压根不带 Origin。把扩展来源加进 OLLAMA_ORIGINS 再重启 Ollama,就是全部的修法。

OLLAMA_ORIGINS 应该设成什么?

chrome-extension://* 是放行任意 Chrome 扩展的写法,也是 SideBoo 需要的值。如果你只想放行一个扩展,就用它的完整 ID —— chrome-extension://<扩展 ID>,在 chrome://extensions 上它自己的卡片里能看到。OLLAMA_ORIGINS 也接受逗号分隔的多个值,所以你可以保留原有的值往后追加,而不是整个替换掉。无论用哪种写法,Ollama 只在启动时读一次这个变量,改完记得重启。

这篇文档解决了你的问题吗?

返回 常见问题