PWA:服务工作者已更新,但未缓存文件

时间:2018-07-14 09:51:18

标签: javascript caching pwa

我目前正在尝试从头开始构建PWA。我在处理更新时遇到了一些麻烦。

基于this article,我编写了一个代码,该代码在服务工作者的新版本可用时显示一个按钮。单击该按钮后,将安装新的工作程序,并将外壳文件存储在缓存中。

要测试此功能,我构建了一个仅包含index.htmlservice-worker.js文件的最小示例。

var cache_version = 'v2';
var cache_name = 'test-pwa-'+cache_version;

var shell_files = [
	'./index.html'
];

self.addEventListener('message', evt => {
	if (evt.data.action == 'skipWaiting')
		self.skipWaiting();
});

self.addEventListener('install', evt => {
	evt.waitUntil(caches.open(cache_name).then(cache => {
		return cache.addAll(shell_files);
	}));
});

self.addEventListener('activate', evt => {
	evt.waitUntil(caches.keys().then(key_list => {
		return Promise.all(key_list.map(key => {
			if (cache_name.indexOf(key) === -1)
				return caches.delete(key);
		}));
	}));
});

self.addEventListener('fetch', evt => {
	evt.respondWith(
		caches.match(evt.request).then(cache_response => {
			return cache_response || fetch(evt.request).then(response => {
				return caches.open(cache_name).then(cache => {
					cache.put(evt.request, response.clone());
					return response;
				});
			});
		})
	);
});
<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8" />
		<title>Test of PWA</title>
	</head>

	<body>
		<h1>Hello World!</h1>

		<p id="refresh" style="display: none;"><button>New update!</button></p>

		<script>
			if ('serviceWorker' in navigator) {
				var new_worker;
				var refreshing = false;

				navigator.serviceWorker.addEventListener('controllerchange', () => {
					if (refreshing)
						return;

					window.location.reload();
					refreshing = true;
				});

				navigator.serviceWorker.register('service-worker.js').then(registration => {
					registration.addEventListener('updatefound', () => {
						new_worker = registration.installing;

						new_worker.addEventListener('statechange', () => {
							if (new_worker.state == 'installed' && navigator.serviceWorker.controller) {
								var notification = document.querySelector('#refresh');

								notification.querySelector('button').addEventListener('click', () => {
									new_worker.postMessage({action: 'skipWaiting'});
								});

								notification.style.display = 'block';
							}
						});
					});
				}).catch(err => {
					console.log('Something went wrong during the registration');
				});
			}
		</script>
	</body>

</html>

现在,我通过例如在标题后面添加新的段落元素来更改HTML文件。然后,我在服务工作者中更改cache_version变量。当我重新加载页面时,将显示更新按钮。当我单击它时,我可以看到(在Firefox工具中)旧缓存已删除,并且按预期方式创建了新的缓存文件夹。但是,index.html文件不会更改(我看不到新段落)。

有什么主意吗?

1 个答案:

答案 0 :(得分:0)

由于C14L的评论,我发现问题出在HTTP缓存中。为了进行调试,我们可以从浏览器的工具中禁用缓存。对于生产而言,我们可以绕过HTTP缓存,也可以使用.htaccess文件对其进行控制。我发现了一些对感兴趣的人有用的信息here