Service Worker 没有停止初始请求并且似乎只使用了一次
Service Worker not stopping initial requests and only appears to be used once
关于这个并得到了一个非常有用的答案,但我仍在努力让它按预期工作,尽管此时我不完全确定我被要求做什么做是可能的。
所以这个服务工作者应该在 ?testMode=true 添加到 URL 时激活,这似乎没问题。然后服务人员应该在特定请求发生之前拦截它们,然后将其重定向到模拟数据。我现在得到的将存储模拟数据并在发出特定请求时调用它,但它实际上并没有阻止初始请求的发生,因为它仍然出现在网络选项卡中。
因此,例如,如果请求包含 /units/all?availability=Active&roomTypeHandle=kitchens,服务工作人员将拦截此请求而不是那个请求,mock-data/unitData。json 应该改用。
这是我目前拥有的:
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.js
const CACHE_NAME = 'mockData-cache';
const MOCK_DATA = {
'/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',
'/products/830368/related?roomTypeHandle=kitchens&productStateHandle=Active&limit=1000&campaignPhaseId=183&retailStore=Finishing%20Touches%20%28Extra%29'
: 'mock-data/relatedItems.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) {
return self.clients.claim();
});
self.addEventListener('fetch', (event) => {
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,
})
);
}
});
另一件我不确定如何解决的事情是 fetch 事件只发生一次。我的意思是当对 serviceWorker.js 进行更改时,模拟数据存储在缓存中并且文件出现在开发工具的网络选项卡中,但是如果我刷新页面,或者关闭它并重新打开另一个选项卡,模拟数据不再位于网络选项卡中,就好像 service worker 根本没有被使用一样。我如何更新它以便始终使用它?我可以在控制台日志中看到 service worker 已注册,但它似乎没有被使用。
抱歉,如果我不应该在 1 个 post 中问 2 个问题,只是真的不确定如何解决我的问题。在此先感谢您的指导。
原来我的问题是范围问题。一旦移动到 service worker 所在的位置,它就会按预期开始工作。意识到是这种情况,因为我发现获取事件实际上并未触发。
所以这个服务工作者应该在 ?testMode=true 添加到 URL 时激活,这似乎没问题。然后服务人员应该在特定请求发生之前拦截它们,然后将其重定向到模拟数据。我现在得到的将存储模拟数据并在发出特定请求时调用它,但它实际上并没有阻止初始请求的发生,因为它仍然出现在网络选项卡中。
因此,例如,如果请求包含 /units/all?availability=Active&roomTypeHandle=kitchens,服务工作人员将拦截此请求而不是那个请求,mock-data/unitData。json 应该改用。
这是我目前拥有的:
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.js
const CACHE_NAME = 'mockData-cache';
const MOCK_DATA = {
'/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',
'/products/830368/related?roomTypeHandle=kitchens&productStateHandle=Active&limit=1000&campaignPhaseId=183&retailStore=Finishing%20Touches%20%28Extra%29'
: 'mock-data/relatedItems.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) {
return self.clients.claim();
});
self.addEventListener('fetch', (event) => {
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,
})
);
}
});
另一件我不确定如何解决的事情是 fetch 事件只发生一次。我的意思是当对 serviceWorker.js 进行更改时,模拟数据存储在缓存中并且文件出现在开发工具的网络选项卡中,但是如果我刷新页面,或者关闭它并重新打开另一个选项卡,模拟数据不再位于网络选项卡中,就好像 service worker 根本没有被使用一样。我如何更新它以便始终使用它?我可以在控制台日志中看到 service worker 已注册,但它似乎没有被使用。
抱歉,如果我不应该在 1 个 post 中问 2 个问题,只是真的不确定如何解决我的问题。在此先感谢您的指导。
原来我的问题是范围问题。一旦移动到 service worker 所在的位置,它就会按预期开始工作。意识到是这种情况,因为我发现获取事件实际上并未触发。