普通网友 2026-01-25 17:00 采纳率: 98.3%
浏览 0
已采纳

Bilibili Helper GitHub 项目如何解决跨域请求被拦截问题?

在开发或调试 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

    1. 确认 Chrome 已启用开发者模式(chrome://extensions → 右上角开关)
    2. 点击「加载已解压的扩展程序」,选择项目根目录(含 manifest.json)
    3. 检查扩展详情页中「站点访问权限」是否包含 https://api.bilibili.com/*
    4. 打开 B 站任意页面,右键 → 「检查」→ 切换到「Application」→ 「Service Workers」确认 background.js 已激活
    5. 在 Content Script 中注入 console.log('CS loaded'),并在 Background 中监听消息并 console.log('BG received') 验证通信通路
    6. 使用 chrome.devtools.network API(需额外权限)捕获后台 fetch 请求原始响应头,排除服务端拦截
    ```
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 今天
  • 创建了问题 1月25日