Service Mocker如何无服务器拦截请求:modern模式Service Worker握手完整原理

发布时间:2026/10/17 5:38:47
Service Mocker如何无服务器拦截请求:modern模式Service Worker握手完整原理 【免费下载链接】service-mocker Next generation frontend API mocking framework项目地址https://gitcode.com/gh_mirrors/se/service-mocker点击查看免费下载在前端开发中API mock接口模拟工具往往需要单独搭建一个 mock 服务器写 JSON、开端口、配代理流程繁琐。而Service Mocker是一个新一代的前端 API mocking 框架它借助Service Worker的机制直接在浏览器内部拦截请求并完成模拟完全不需要任何真实服务器。本文完整拆解 Service Mocker 在 modern 模式下的 Service Worker 握手原理客户端如何与服务工作者建立连接又如何拿到拦截请求的权限。一图看懂整体架构Service Mocker 的典型用法只有两个文件server.js服务器脚本用 express 风格的路由定义模拟规则它实际上是被注册为 Service Worker 运行的app.js客户端脚本页面中唯一需要引入的脚本负责与 Service Worker 完成握手。// server.js —— 定义模拟规则 import { createServer } from service-mocker/server; const { router } createServer(); router.get(/greet, (req, res) { res.send(Hello new world!); });握手完成后页面发起的任何fetch/XMLHttpRequest请求都会被 Service Worker 截获命中路由规则就返回模拟数据请求根本不会走到真实网络。这就是无服务器拦截的核心。⚡模式判定modern 还是 legacyService Mocker 内部有两种工作模式入口在 src/client/index.js 的createClient()中自动选择判定条件结果浏览器支持 Service WorkerserviceWorker in navigator继续判定页面运行在安全环境HTTPS或localhost/127.0.0.1✅ 创建ModernClientService Worker 模式任一条件不满足⚠️ 控制台警告并降级为LegacyClientmonkey-patch 模式另外也支持显式指定createClient(server.js, { forceLegacy: true })可强制使用 legacy 模式。本文聚焦 modern 模式——这也是 Service Mocker 的完全体。握手第一步注册 Service WorkerModernClient初始化时调用 src/client/modern/register.js 中的register()核心只做两件事navigator.serviceWorker.register(scriptURL, { scope: location.pathname })—— 把你的 server.js 注册为 Service Worker作用域限定在当前页面路径注册成功后立即调用connect()进入握手阶段。这里有一个容易踩坑的细节根据浏览器规范Service Worker 的作用域默认不能超过脚本自身所在路径。如果你的 server.js 放在非根路径如assets/js/server.js需要在 dev server 上配置Service-Worker-Allowed响应头来解除限制详见 docs/caveats.md。握手核心connect 与 handshake 逐帧解析握手逻辑集中在 src/client/modern/connect.js流程如下① 等待 Worker 就绪先记录hasController当前页面是否已被某个 Worker 控制然后await navigator.serviceWorker.ready。注释里写得很清楚Chrome 在页面重载后有时会卡住所有动作都要等 Worker 就绪后再执行。② 获取最新注册如果页面已有控制器且未跳过更新检查会走 src/client/modern/get-newest-reg.js 的getNewestReg()执行registration.update()探测新版本发现新 Worker 后等待其激活statechange到activated否则直接getRegistration()拿到当前注册对象。③ 发送握手机器码拿到注册对象后handshake()执行两跳消息顺序消息发送条件作用1mocker/request_claim页面尚无控制器首次安装等未受控状态请求 Worker 立即接管当前页面2mocker/ping总是发送探活并确认通道连通等待mocker/pong回包所有动作常量定义在 src/constants/action.js并统一加上mocker/前缀以避免与其他页面的消息冲突。握手成功后控制台会打印[mocker:modern] connection established消息是怎么传输的消息通道由 src/utils/send-message-request.js 实现每次通信创建一个MessageChannel通过port1/port2成对传递收到回复后立即关闭端口释放内存内置3 秒超时超时会抛出messaging timeout错误——所以如果握手长时间不完成通常是 Worker 没有成功加载回复中若带error字段则以 reject 抛出否则 resolve。可以把它理解成一次轻量级的TCP 三次握手请求—应答—确认。Worker 端的回应claim 接管是关键握手的服务端实现非常简洁就在 src/server/server.js 的事件监听里收到PING→ 回一个PONG收到REQUEST_CLAIM→ 先执行await self.clients.claim()再回ESTABLISHED。为什么要clients.claim()因为按 Service Worker 默认行为新安装的 Worker 只会接管之后新打开的页面当前已存在的页面不会被控制。claim()让 Worker 主动接管所有已打开的客户端页面这正是无服务器拦截能够立即生效的前提。另外两个生命周期细节也值得注意self.addEventListener(install, (event) { event.waitUntil(self.skipWaiting()); // 新版本不排队直接激活 }); self.addEventListener(activate, (event) { event.waitUntil(self.clients.claim()); // 激活时接管所有页面 });skipWaiting()保证路由规则一改就能生效不用反复强刷activate里的claim()则确保页面重载后依然处于受控状态。握手完成后请求是如何被拦截的握手的意义在于拿到控制权和确认连通性真正的拦截发生在 Service Worker 的fetch事件上。同样在 src/server/server.js 中self.addEventListener(fetch, (event) { MockerRouter.routers.some((router) { return router._match(event); // 逐个路由表尝试匹配 }); });匹配逻辑在 src/server/router.js 的_match()中依次校验请求 origin 与路由所属 origin 一致去掉 baseURL 前缀后路径命中path-to-regexp规则HTTP 方法匹配或注册了all。命中后同步构造MockerRequest和MockerResponse先跑完所有中间件再执行你写的回调res.send(...)/res.json(...)等。由于这一切都发生在 Service Worker 上下文内返回的仍是标准Response对象——在浏览器 Network 面板里能看到真实的请求与响应头调试体验与真接口几乎无差别。✅容易忽略的三个细节client.ready之前任何请求都不会被拦截。这是官方文档docs/api.md明确强调的所有初始化代码应放进client.ready.then(...)里执行否则页面启动早期的请求会直接打到真实网络Worker 更新自动重连src/client/modern/client.js 的_autoSyncClient()监听controllerchange事件Worker 升级后自动与新 Worker 重新握手此时跳过更新检查并在控制台提示 mocker updated, reload your requests to take effect同一端口多项目会互相干扰因为 Worker 按 origin scope 拦截请求切换到一个没有 mock 的项目时可能被误拦截此时可调用client.unregister()或到浏览器开发者工具中手动注销 Worker详见 docs/caveats.md。快速上手清单 安装仅开发依赖即可npm install service-mocker --save-dev编写 server.js 定义路由参考上文示例完整 API 见 docs/api.md页面中仅引入客户端脚本createClient(server.js)后在client.ready.then(...)中发请求用http://localhost:3000这类本地地址打开页面localhost 免 HTTPS满足安全环境要求看到控制台输出[mocker:modern] connection established说明 Service Worker 握手成功拦截已就绪。写在最后Service Mocker 的 modern 模式用一次Service Worker 握手替代了传统 mock 方案里整个服务器register注册、claim接管、PING/PONG确认、fetch事件拦截——每一步都依托浏览器原生能力零依赖、零端口、零代理。理解这套握手流程后你就能准确判断 mock 为何没生效是没握手成功等ready、是作用域限制scope 路径问题还是 Worker 被残留的旧注册占用unregister 即可。更多使用细节可以查看仓库内的 README.md 与 docs/api.md。赞分享【免费下载链接】service-mocker Next generation frontend API mocking framework项目地址https://gitcode.com/gh_mirrors/se/service-mocker点击查看免费下载相关推荐Service Mocker源码阅读MockerRouter与MockerResponse请求拦截流程全剖析Service Mocker源码阅读MockerRouter与MockerResponse请求拦截流程全剖析 Service Mocker 是一个基于 SerMSWMock Service Worker前端请求模拟利器MSWMock Service Worker前端请求模拟利器 项目介绍 MSW 是一个强大的服务工作者库专为 mocking API 请求而设计允许开测试开发工具前端Mock Service Worker模拟API请求的开源利器Mock Service Worker模拟API请求的开源利器 Mock Service WorkerMSW是一个用于浏览器和Node.js的开源库主要测试开发工具前端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询