在开发或调试 Bilibili Helper(如 GitHub 上的 bilibili-helper、bilibili-evolved 等浏览器扩展)时,常见问题:向 `api.bilibili.com` 或其他 B 站接口发起跨域 AJAX 请求时被浏览器拦截(CORS 错误)。根本原因在于——这些请求由前端 JavaScript 直接发出,而 B 站服务端未对普通网页源(如 `localhost:3000`)返回 `Access-Control-Allow-Origin` 头。Bilibili Helper 项目**不依赖服务端代理**,而是通过 Chrome/Firefox 扩展的特权能力绕过 CORS:在 `manifest.json` 中声明 `host_permissions`(如 `"https://api.bilibili.com/*"`),并使用 `chrome.runtime.sendMessage` + `content script` 配合 `background service worker` 发起请求——此时请求以扩展身份执行,不受同源策略限制。注意:该方案仅适用于已安装的合法扩展,无法在普通网页中复现;若本地开发调试,需确保加载的是 unpacked extension 且权限配置正确。
1条回答 默认 最新
Jiangzhoujiao 2026-01-25 17:00关注```html一、现象层:CORS 错误的典型表现与日志特征
- 控制台报错:
Access to fetch at 'https://api.bilibili.com/x/web-interface/archive/stat?bvid=BV1xx411c7mu' from origin 'http://localhost:3000' has been blocked by CORS policy - Network 面板中请求状态为
(blocked:cors),Response Headers 完全为空(无Access-Control-Allow-Origin) - 该错误仅出现在直接调用
fetch()或XMLHttpRequest时;若通过chrome.runtime.sendMessage中转则无此报错 - 在普通网页(如本地 HTML 文件或 React/Vue 开发服务器)中必现;而加载为 unpacked extension 后消失——这是关键分水岭
二、机制层:浏览器同源策略与扩展特权模型的双轨制
现代浏览器对跨域请求实施两级隔离:
维度 普通网页上下文 Chrome 扩展上下文(Content Script / Service Worker) 同源策略作用对象 页面 origin(协议+域名+端口) 不适用;扩展拥有独立权限域( extension://[id]/)网络请求发起主体 受限于页面 origin 的沙箱 以扩展身份运行,受 host_permissions白名单约束,非 CORS 检查服务端响应头要求 必须返回匹配的 Access-Control-Allow-Origin完全忽略;B站无需、也不会为此类请求添加 CORS 头 三、配置层:manifest.json 权限声明的演进与陷阱
从 Manifest V2 到 V3 的关键迁移要点:
// manifest.json (V3) { "manifest_version": 3, "permissions": ["storage", "scripting"], "host_permissions": [ "https://api.bilibili.com/*", "https://api.bilibili.tv/*", "https://data.bilibili.com/*" ], "content_scripts": [{ "matches": ["https://www.bilibili.com/*"], "js": ["content.js"] }], "background": { "service_worker": "background.js" } }- ⚠️ 常见错误:将 API 域写成
"api.bilibili.com/*"(缺协议)或"*://api.bilibili.com/*"(通配协议不被 V3 支持) - ✅ 最佳实践:显式声明 HTTPS 协议 + 路径通配;避免使用
<all_urls>(审核风险高且不必要)
四、架构层:跨进程通信链路与请求代理模式
graph LR A[Content Script] -->|chrome.runtime.sendMessage| B[Background Service Worker] B -->|fetch API| C[https://api.bilibili.com/x/...] C -->|JSON Response| B B -->|chrome.runtime.sendMessage| A style A fill:#4A90E2,stroke:#357ABD style B fill:#50E3C2,stroke:#2A8F72 style C fill:#F5A623,stroke:#D08B00该架构实现「前端逻辑解耦」与「网络权限收口」双重目标:
- Content Script 负责 DOM 注入、用户交互监听,不触碰网络
- Background Service Worker 作为唯一可信网络出口,集中处理鉴权(
document.cookie自动携带)、重试、缓存策略 - 消息通道天然支持 Promise 化封装,例如:
browser.runtime.sendMessage({type:'api', url:'/x/web-interface/archive/stat', params:{bvid}})
五、调试层:unpacked extension 开发验证 checklist
- 确认 Chrome 已启用开发者模式(
chrome://extensions→ 右上角开关) - 点击「加载已解压的扩展程序」,选择项目根目录(含 manifest.json)
- 检查扩展详情页中「站点访问权限」是否包含
https://api.bilibili.com/* - 打开 B 站任意页面,右键 → 「检查」→ 切换到「Application」→ 「Service Workers」确认 background.js 已激活
- 在 Content Script 中注入
console.log('CS loaded'),并在 Background 中监听消息并console.log('BG received')验证通信通路 - 使用
chrome.devtools.networkAPI(需额外权限)捕获后台 fetch 请求原始响应头,排除服务端拦截
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报- 控制台报错: