尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
如何优雅拦截 fetch 与 SSE 流?Claude Counter 注入层 bridge.js 源码实战
如何优雅拦截 fetch 与 SSE 流Claude Counter 注入层 bridge.js 源码实战【免费下载链接】claude-counterA minimal browser extension that shows token count, cache timer, and usage bars on claude.ai.项目地址: https://gitcode.com/gh_mirrors/cl/claude-counterClaude Counter 是一款轻量级浏览器扩展在 claude.ai 页面上实时显示 token 数、缓存倒计时和用量进度条。它实现这些功能的秘诀正是优雅地拦截 fetch 请求与 SSEServer-Sent Events流式响应——整个注入层由一个仅约 180 行的 bridge.js 完成。本文将带你读懂这套注入层 消息桥的经典架构新手也能轻松理解浏览器扩展拦截网络请求的完整套路。 为什么需要注入层Content Script 的权限盲区很多新手会踩第一个坑直接在 content script 里写window.fetch ...发现页面自己的请求根本拦不到。原因很简单——content script 运行在隔离世界isolated world它有独立的window对象。页面应用调用的是它自己世界里的fetch两者互不可见。Claude Counter 的解法非常干净通过script标签把 bridge.js 注入到页面主世界main world注入动作由 bridge-client.js 中的injectBridgeOnce()完成用runtime.getURL(src/injected/bridge.js)取出脚本地址且靠getElementById检查保证只注入一次SPA 不刷新页面脚本不能重复跑manifest.json 中把该文件声明为web_accessible_resources这是脚本能被页面加载的前提。一句话总结隔离世界负责搭桥主世界负责偷听网络。⏱️ 抢在框架之前先存原件再包一层拦截网络请求最忌讳包了又包、丢了原件。bridge.js 在文件最开头就做了两件关键动作const originalFetch window.fetch; // 抢在任何人之前保存原件 const originalPushState history.pushState.bind(history);随后再给window.fetch包一层 async 代理。这里有个容易忽略的细节包fetch的同时还包了history.pushState / replaceState——因为 claude.ai 是单页应用切换会话时 URL 会变但页面不刷新而前端框架可能会提前缓存这些方法。bridge.js 抢在框架初始化前包裹它们每次导航就派发一个cc:urlchange自定义事件main.js 侧监听该事件即可及时刷新 token 统计。 核心原则注入脚本一定要尽早执行保存原始引用再用调用原件 旁路处理的方式包装。 优雅拦截 fetch只挑自己关心的请求包裹后的fetch代理并不是无脑处理所有请求而是精准识别三类流量请求特征识别条件用途生成开始信号POST且 URL 含/completion或/retry_completion派发cc:generation_startUI 开始显示缓存倒计时SSE 流式响应content-type含event-stream进入流解析提取实时用量会话树数据URL 含/chat_conversations/且带tree参数用正则提取orgId与conversationId供 token 统计注意 bridge.js 第 70-78 行 的toAbsoluteUrl()fetch的入参可能是字符串、URL或Request对象三种形态都做了归一化——这种防御性处理是拦截层代码的标配。 解析 SSE 流克隆响应 逐行缓冲这是整篇文章最值得学的一段。页面正在消费一个流式响应你不能直接读它的 body会掐断页面的流。Claude Counter 的做法是response.clone()克隆一份响应让页面和插件各读各的在克隆体上调用body.getReader()拿流读取器用TextDecoder带{ stream: true }增量解码解决分片恰好把一个data:行切成两半的问题按\r\n|\r|\n切行最后一行不完整就留在 buffer 等下一片只挑data:开头的行解析 JSON命中type message_limit时通过消息桥转发出去。对应源码在 handleEventStream。这段流解析拿到的message_limit是未四舍五入的精确用量比 Claude 官方/usage页面的取整百分比更准——这正是插件进度条更精确的来源。 消息通道两个世界如何对话注入脚本主世界与 content script隔离世界之间没有共享变量只能靠window.postMessage。Claude Counter 定义了一套极简协议统一标记所有消息都带cc: ClaudeCounter字段双方收到消息先校验标记避免误吞页面其他脚本的 postMessage事件单向推送如cc:generation_start、cc:conversation、cc:message_limitcontent script 侧用bridge.on(type, fn)订阅请求-响应配对BridgeClient.request() 生成requestId把 Promise 的 resolve/reject 存进_pendingMap等cc:response回来时按 id 取走结算并附带超时自动清理。bridge.js 侧收到cc:request后按kind分发目前支持三种任务见 消息监听器hash用页面世界的crypto.subtle计算 SHA-256 摘要content script 拿不到该 APIusage以credentials: include调用/usage接口借用页面 Cookie 身份conversation拉取会话树 JSON 并转发。️ 容错哲学插件绝不能拖垮宿主页面翻遍 bridge.js 源码会发现大量try/catch且捕获后一律静默降级ignore parse failures、best-effort; dont break claude.ai。再对比 main.js 中刷新失败也只是 return 不报错——这体现了一个成熟扩展的底线思维拦截层旁路失败不影响主流程clone 解析失败跳过页面请求照常返回SSE 读取全程尽力而为任何异常都吞掉所有数据本地处理不上传任何外部服务器见 README 的 Privacy 一节。 动手看源码推荐阅读路径想完整走一遍数据流按这个顺序读src/injected/bridge.js —— 注入层fetch 拦截 SSE 解析 请求分发src/content/bridge-client.js —— 客户端注入脚本 消息桥src/content/main.js —— 调度层URL 变化、用量刷新、SSE 事件消费manifest.json —— 权限与资源声明另外不想装扩展的同学还可以直接看油猴版实现 userscript/claude-counter.user.js它把注入逻辑直接内嵌进脚本适合对比两种分发形态的差异。✅ 总结拦截 fetch 与 SSE 的四个黄金动作一句话记住全文尽早保存原始引用originalFetch再包一层异步代理精准识别目标流量用 URL/方法/content-type过滤别处理无关请求response.clone()getReader()无损旁读 SSE 流注意分片缓冲postMessage requestId 协议打通隔离世界并用标记字段防串扰。Claude Counter 用不到 200 行代码展示了浏览器扩展网络拦截的完整范式无论是做 AI 用量监控、接口调试工具还是页面增强插件这套注入层 消息桥的架构都值得直接借鉴。【免费下载链接】claude-counterA minimal browser extension that shows token count, cache timer, and usage bars on claude.ai.项目地址: https://gitcode.com/gh_mirrors/cl/claude-counter创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

Codex本地代理实战:用Node.js+tmux+YAML构建可定制AI编程胶水层

Codex本地代理实战:用Node.js+tmux+YAML构建可定制AI编程胶水层

1. OpenRig 是什么:一个被误读的开源工具链命名陷阱OpenRig 这个词在当前技术社区里,正经历一场典型的“命名漂移”现象——它既不是某个广为人知的成熟项目,也不是官方发布的标准工具,而更像是一组围绕Codex(GitHub C…

📅 2026/10/4 6:37:47
智能体支付重复扣款?从重试机制到幂等设计的工程实践

智能体支付重复扣款?从重试机制到幂等设计的工程实践

凌晨两点,我盯着后台日志里那条醒目的报错记录陷入了沉思。日志显示,一个智能体在调用支付接口时,第一次请求超时触发了自动重试,第二次调用成功了。但问题在于,第一次请求其实也已经处理成功了,只是响应报…

📅 2026/10/4 6:37:47
缠论核心三要素:中枢、走势类型与买卖点的结构化解析

缠论核心三要素:中枢、走势类型与买卖点的结构化解析

1. 这不是玄学,是可验证的市场行为结构分析法“缠中说禅交易指南”这六个字,在国内金融实操圈里,几乎等同于一个暗号。它不指向某个具体软件、平台或课程,而是一套以《缠论》为内核、经多年市场验证形成的完整交易思维体系。我从2…

📅 2026/10/4 6:37:47
MORE NEWS

更多资讯

📰

Linux 内核揭秘:用户空间程序的启动过程——从 `_start` 到 `main` 的完整调用链

文档教程操作系统 【免费下载链接】linux-insides-zh Linux 内核揭秘 项目地址: https://gitcode.com/gh_mirrors/li/linux-insides-zh 点击查看 免费下载 导读 main 函数并不是 C 程序的真正入口。当你在 Linux 上执行一个程序时,内核通过 execve 系统…

📰

Android MVVM 架构模式实战指南:ViewModel、LiveData 与 StateFlow 在 developer-roadmap 中的系统解读

文档教程知识库 【免费下载链接】developer-roadmap Interactive roadmaps, guides and other educational content to help developers grow in their careers. 项目地址: https://gitcode.com/GitHub_Trending/de/developer-roadmap 点击查看 免费下载 MVVM&…

📰

OpenShell:把Win10/Win11开始菜单调回经典样式,安装配置与进阶玩法全攻略

如果你是从 Windows 7 一路用过来的老用户,第一次面对 Windows 8/10/11 那个铺满磁贴和推荐应用的新开始菜单时,多半会有一种感觉:微软把我用了几十年的入口换掉了,我却连控制面板都找不着。我第一次升级到 Win10 之后真的纠结了很…

📰

JavaWeb学生信息管理系统大作业:完整源码+建表SQL+课程设计报告,跑通CRUD全流程

简介:这是一套面向计算机相关专业学生的 JavaWeb 期末大作业完整项目,以学生信息管理系统为主题,适合正在准备课程设计、期末大作业或需要项目实战练习的学习者参考使用。项目结构完整,包含源代码、数据库建表脚本与配套课程设计报…

📰

主流AI论文工具梯队榜(2026 深度测评)

基于功能完整性、学术适配性、用户反馈及操作便捷性,以下是当前主流AI论文写作工具的深度测评榜单,按综合使用价值从高到低进行排序,并附上核心功能亮点与适用人群说明。🏆 第一梯队:全流程学术解决方案(★…

📰

Android Ext4文件系统故障排查:从Journal机制到fsck实操

前阵子帮朋友排查一台老设备的Android系统,现象是重启后一直卡在开机动画,进了Recovery发现/data分区挂载失败。折腾了一整天,最后定位到是Ext4文件系统的journal区域出现了坏块。类似的坑我踩过不止一次,而且现在网上关于Android…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬