Skip to content

1.1 MSW 是什么 ​

… 正在启动 Mock Worker

🌐 本教程的在线站点:https://yzhijie.github.io/msw-tutorial/ ,其中漫画剧场也一并部署;每次向源码仓库推送 main,站点会由 Actions 自动重新构建发布。

Mock Service Worker(MSW) 是一个 API 模拟工具:它使用 Service Worker(浏览器)或 请求拦截(Node) 在应用的网络层截获请求,并用你编写的 handler 返回模拟响应。

应用代码完全无感知 —— 你写的还是普通的 fetch("/api/users"),浏览器 DevTools 的 Network 面板里甚至能看到这条"请求"以及它的状态码、响应头和响应体。

为什么需要它 ​

在前后端分离的项目里,前端开发常常面临:

痛点传统做法(手写 mock / json-server / 改代码)MSW 的做法
后端接口没就绪业务代码里写死假数据,联调前再删真实发请求,网络层返回,业务代码零侵入
想测 500 / 超时手动改代码或后端配合一个开关切换错误状态与延迟
单元测试 mock 与开发 mock 两套vi.mock 与 mock 文件各写一份同一套 handler,浏览器和 Node 共用
DevTools 看不到请求数据凭空出现,难以排查请求真实经过网络栈,Network 面板完整可见
想模拟 WebSocket依赖 mock-socket 等三方库MSW 3 内置原生 WebSocket 拦截

核心理念一句话:mock 应该发生在网络边界上,而不是散落在应用代码里。

工作原理(浏览器) ​

  你的应用                    浏览器网络栈                    真实服务器
 ┌──────────┐   fetch()    ┌─────────────────────┐
 │ 业务代码 │ ───────────▶ │ Service Worker 注册  │
 │ (无感知) │              │  mockServiceWorker  │
 └──────────┘              └─────────┬───────────┘        ┌──────────┐
       ▲                            │ 匹配 handler?       │ 后端 API │
       │  Response                  ▼                     └──────────┘
       │                    ┌─────────────────┐
       └────────────────────│ 你的 handlers    │
        状态码/头/JSON/延迟  │ http/ws/graphql │
                            └─────────────────┘
                                  │ 未匹配
                                  ▼
                            passthrough() → 放行到真实服务器

三个角色(本教程漫画「信标驿站」里的拟人化设定):

  1. 请求小邮差:你应用发出的每个 HTTP / WS 请求。
  2. Worker 站长:注册在页面同源下的 mockServiceWorker.js,所有出域请求先经过它,按规则决定"自己回信"还是"放行"。
  3. 服务端大熊:真实后端(或 MSW 在 Node 测试里扮演的拦截层)。

MSW 3 的关键变化(v2 → v3 迁移要点) ​

本教程基于 MSW 3.0.x,如果你见过 v1/v2 的教程,以下差异必须记住:

  1. 命名空间按协议拆分子路径:
    • http、HttpResponse 仍从 msw 导入;
    • graphql 改为从 msw/graphql 导入(并需要 peer 依赖 graphql);
    • WebSocket 的 ws 从 msw/ws 导入。
  2. 原生 WebSocket:ws.link("ws://…") + 事件驱动 API,不再需要 mock-socket。
  3. onUnhandledRequest 更名为 onUnhandledFrame,统一表示"未处理的 HTTP 请求 / WS 帧"。
  4. handler 数组类型用 AnyHandler[](HTTP 与 WS handler 的联合)。
  5. 浏览器客户端事件只有 open / message / close(没有独立 error 事件上的帧语义,错误通过关闭码表达)。
  6. 官方提供 msw/vite 插件(virtual:msw)作为可选的零文件集成方式;本教程使用经典的 public/mockServiceWorker.js 方式,原理更透明。

本教程怎么学 ​

  • 第二章:5 分钟把 worker 跑起来;
  • 第三 ~ 六章:按"启动 → 拦截 → 响应 → 高级"的顺序系统讲解 API;
  • 第七章:综合场景与交互实验室 —— 本页面右上角的徽章如果显示"拦截中",说明你此刻就可以直接在文档里发请求。

想要完整工程?仓库提供两个功能完全对等的独立可运行示例:

bash
pnpm dev:react   # http://localhost:5173  React 19 + TypeScript
pnpm dev:vue     # http://localhost:5174  Vue 3.5 + Pinia + TypeScript

不想 clone 仓库?也可以在 StackBlitz(WebContainers)中在线打开整个 monorepo 运行: 在 StackBlitz 中打开。 (仓库为私有访问时,需先在 StackBlitz 登录 GitHub 并完成授权。)