Workbox предоставляет мощный инструмент для работы с Service Worker и управлением кэшированием ресурсов на клиентской стороне. Одной из ключевых возможностей является перехват и мокирование запросов Fetch, что позволяет создавать гибкие стратегии кэширования и тестирования сетевых запросов без изменения серверного кода.
workbox-routingДля начала работы с мокированием запросов используется модуль
workbox-routing. Он позволяет определить правила
маршрутизации и сопоставления URL-запросов с обработчиками.
Пример базового перехвата всех GET-запросов к API:
import { registerRoute } from 'workbox-routing';
import { NetworkFirst } from 'workbox-strategies';
registerRoute(
({ url }) => url.pathname.startsWith('/api/'),
new NetworkFirst()
);
В этом примере стратегия NetworkFirst сначала пытается
получить данные с сети, а при недоступности сети — возвращает
кэшированные данные. Для мокирования такой подход можно комбинировать с
собственными обработчиками.
Workbox позволяет создавать кастомные обработчики, возвращающие статические данные или динамически формируемый ответ вместо обращения к реальному серверу.
Пример мокирования запроса к /api/user:
import { registerRoute } from 'workbox-routing';
registerRoute(
({ url }) => url.pathname === '/api/user',
async () => {
return new Response(JSON.stringify({
id: 1,
name: 'John Doe',
role: 'admin'
}), {
headers: { 'Content-Type': 'application/json' }
});
}
);
Здесь при любом запросе к /api/user клиент всегда
получит заранее определённый JSON, что полезно для разработки и
тестирования интерфейсов без задействования реального API.
Часто возникает необходимость сочетать мокирование с кэшированием. Workbox позволяет реализовать гибридные стратегии, например, отдавать мокированные данные при оффлайне, а при наличии сети обновлять кэш.
import { CacheFirst } from 'workbox-strategies';
registerRoute(
({ url }) => url.pathname.startsWith('/api/products'),
async ({ event }) => {
try {
const response = await fetch(event.request);
return response;
} catch (error) {
return new Response(JSON.stringify([
{ id: 101, name: 'Product A' },
{ id: 102, name: 'Product B' }
]), { headers: { 'Content-Type': 'application/json' } });
}
}
);
В этом примере сначала пробуется сетевой запрос, и только при его неудаче возвращается мокированный ответ. Такой подход облегчает разработку offline-first приложений.
workbox-precaching для статических моковИногда необходимо заранее закэшировать набор статических JSON-файлов,
чтобы мокирование было полностью автономным. Для этого используется
workbox-precaching:
import { precacheAndRoute } from 'workbox-precaching';
precacheAndRoute([
{ url: '/mock/users.json', revision: '1' },
{ url: '/mock/products.json', revision: '1' },
]);
registerRoute(
({ url }) => url.pathname.endsWith('/api/users'),
async () => {
return caches.match('/mock/users.json');
}
);
Такой подход позволяет полностью контролировать данные на клиентской стороне без сетевых зависимостей.
Workbox позволяет обрабатывать GET-запросы с query-параметрами. Для этого можно анализировать URL и формировать ответы динамически:
registerRoute(
({ url }) => url.pathname === '/api/search',
({ url }) => {
const query = url.searchParams.get('q');
const results = query ? [`Result for "${query}"`] : [];
return new Response(JSON.stringify(results), {
headers: { 'Content-Type': 'application/json' }
});
}
);
Такой подход позволяет имитировать поведение API при поисковых запросах, полностью на клиентской стороне, без обращения к серверу.
Для упрощения разработки полезно логировать все перехваченные запросы:
registerRoute(
({ url }) => url.pathname.startsWith('/api/'),
async ({ request }) => {
console.log('Intercepted request:', request.url);
return new Response(JSON.stringify({ mocked: true }), {
headers: { 'Content-Type': 'application/json' }
});
}
);
Логи помогают следить за тем, какие запросы мокируются и корректно ли обрабатываются сценарии offline и online.
Content-Type и Cache-Control, чтобы не
возникало конфликтов с реальными ответами сервера.