使用 ServiceWorker 拦截和重定向请求 [英] Using ServiceWorker to intercept and redirect requests

查看:307
本文介绍了使用 ServiceWorker 拦截和重定向请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我被要求创建一个 Service Worker,它能够拦截请求并将它们重定向到存储的模拟数据.我以前从未做过这样的事情,所以我有点挣扎.当 testMode=true 添加到 URL 时,服务工作者被激活.我有 2 个文件需要处理.这是我目前所拥有的:

I've been asked to create a service worker which will have the ability to intercept requests and redirect them to stored mock data. I have never done something like this before so I am struggling a bit. The service worker is activated when testMode=true is added to the URL. I have 2 files for dealing with. This is what I have so far:

TestMode.ts

TestMode.ts

class TestMode {
    constructor() {
        if (!this.isEnabled()) {
            return;
        }

        if (!('serviceWorker' in navigator)) {
            console.log('Browser does not support service workers');
            return;
        }

        this.init();
    }

    private init(): void {
        navigator.serviceWorker
            .register('planner-worker/js/worker.min.js')
            .then(this.handleRegistration)
            .catch((error) => { throw new Error('Service Worker registration failed: ' + error.message); });

        navigator.serviceWorker.addEventListener('message', event => {
            // event is a MessageEvent object
            console.log(`The service worker sent me a message: ${event.data}`);
        });

        navigator.serviceWorker.ready.then( registration => {
            if (!registration.active) {
                console.log('failed to communicate')

                return;
            }

            registration.active.postMessage("Hi service worker");
        });
    }

    private handleRegistration(registration: ServiceWorkerRegistration): void {
        registration.update();

        console.log('Registration successful, scope is:', registration.scope);
    }

    private isEnabled(): boolean {
        return locationService.hasParam('testMode');
    }
}

export default new TestMode();

serviceWorker.ts

serviceWorker.ts

const CACHE_NAME = 'mockData-cache';

const MOCK_DATA: Record<string, string> = {
    '/units/all?availability=Active&roomTypeHandle=kitchens': 'mock-data/unitData.json',
    '/frontal-ranges/kitchens?' : 'mock-data/kitchensData.json',
    '/carcase-ranges/?availability=Active&roomTypeHandle=kitchens' : 'mock-data/carcaseRangesData.json'
};


self.addEventListener('install', event => {
    console.log('Attempting to install service worker and cache static assets');
    event.waitUntil(
        caches.open(CACHE_NAME)
            .then(cache => {
                return cache.addAll(Object.values(MOCK_DATA));
            })
    );
});


self.addEventListener('activate', function(event) {
    console.log('Claiming control');
    return self.clients.claim();
});
self.addEventListener( "fetch", event => {
    console.log('WORKER: Fetching', event.request);
});

到目前为止我所做的工作,服务工作者已注册,模拟数据 json 文件存储在缓存中.

What I have so far works, the service worker is registered and that mock data json files are stored in the cache.

我不确定该怎么做的是,当发出某个请求时,Service Worker 将使用存储在缓存中的模拟数据.

What I am not sure what to do is when a certain request is made, the service worker will use the mock data stored in the cache instead.

例如,我怎样才能得到它,以便在发出以下请求时:/units/all?availability=Active&roomTypeHandle=kitchens 服务工作者将重定向到缓存中的 mock-data/unitData.json?

For example, how can I get it so that when the request is made for: /units/all?availability=Active&roomTypeHandle=kitchens the service worker will redirect to mock-data/unitData.json in the cache instead?

我希望我说得有道理,任何帮助都将不胜感激,这对我来说是全新的.

I hope I've made sense, any help would be really appreciated, this is all new to me.

推荐答案

处理传入请求和生成响应(来自缓存、网络或两者的某种组合)的逻辑需要在您的 fetch 事件处理程序.

The logic around handling incoming requests and generating responses (either from the cache, network, or some combination of the two) needs to be implemented in your fetch event handler.

根据您的缓存内容和用例,我将如何构建您的 fetch 处理程序:

Here's how I'd structure your fetch handler given your cache contents and use case:

self.addEventListener('fetch', (event) => {
  // Using a URL object will make routing easier.
  const url = new URL(event.request.url);
  const pathAndQuery = url.pathname + url.search;

  if (pathAndQuery in MOCK_DATA) {
    const cacheKey = MOCK_DATA[pathAndQuery];
    event.respondWith(
      caches.match(cacheKey, {
        cacheName: CACHE_NAME,
      })
    );
  }

  // If pathAndQuery isn't in MOCK_DATA, then respondWith()
  // won't be called, and the default network behavior will
  // be used for this request.
});

您也许可以使用像 https://mswjs.io/ 这样的库来替代编写这是手工完成的,但如果您决定自己动手,这就是一般的想法.

You might be able to use a library like https://mswjs.io/ as an alternative to writing this by hand, but that's the general idea if you decide to do it yourself.

这篇关于使用 ServiceWorker 拦截和重定向请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆