safari - Safari service worker work incorrect with custom offline page
问题描述
I created a pwa version of the site with a custom offline page using the service worker. When navigating through pages, they are added to the cache, and when they are visited again, it is shown from the cache. When you click on a link and do not connect to the Internet and this page is not cached, an offline page is displayed.
There are 2 options to refresh the page:
- When the Internet appears on the offline page, a link appears to update the page.
- When the Internet appears, return to any available page (home
page) and go to the desired page.
With the first option there is no problem. And with the second there is a problem in the safari. The problem occurs when:
- clicked on the link without an Internet connection and received an offline page
- The next time already with the Internet connection went on the same link and again received an offline page, although it should show an online page
Steps to reproduce the problem:
- go to the site with the Internet turned on
- turn off the Internet
- go to page1.html (an offline page is displayed)
- go back to index.html (go home link)
- turn on the internet
- go back to page1.html (an offline page is displayed, but page1.html should be displayed)
- go to page2.html - everything works correctly, the online page loads
Who faced such a problem? It seems that the safari remembers request-response bunch and return the same result, regardless of the connection to the Internet.
'use strict';
const CACHE_VERSION = 1;
const BASE_URL = location.origin + '/';
const OFFLINE_URL = '/offline.html';
const CURRENT_CACHES = {
offline: 'offline-v' + CACHE_VERSION,
};
const URLS_TO_CACHE = [
BASE_URL,
OFFLINE_URL,
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CURRENT_CACHES.offline)
.then(cache => {
return cache.addAll(URLS_TO_CACHE);
})
.then(() => {
return self.skipWaiting()
})
);
});
self.addEventListener('activate', event => {
let expectedCacheNames = Object.keys(CURRENT_CACHES).map(function (key) {
return CURRENT_CACHES[key];
});
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (expectedCacheNames.indexOf(cacheName) === -1) {
return caches.delete(cacheName);
}
})
);
})
.then(() => {
return self.clients.claim()
})
);
});
// fetch requests
self.addEventListener('fetch', event => {
const responsePromiseFactory = () => {
return caches.open(CURRENT_CACHES.offline).then((cache) => {
return cache.match(event.request).then(response => {
if (response) {
return response;
}
const fetchRequest = event.request.clone();
return fetch(fetchRequest)
.then(response => {
const responseToCache = response.clone();
if (!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
cache.put(event.request, responseToCache)
return response;
})
})
})
.catch(error => {
return caches.match(OFFLINE_URL)
})
};
event.respondWith(responsePromiseFactory());
});
Tested on safari desktop v.11.1 and mobile safari ios version 11.3.1
解决方案
我遇到了完全相同的情况,通过在我的离线页面中添加以下标题,Safari 现在在互联网连接可用时为在线页面提供服务。
<head>
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="pragma" content="no-cache" />
</head>
推荐阅读
- xpath - Handling
tag in xpath through cucumber - excel - Excel VBA - 在一张纸上找到并粘贴到另一个向下移动的目标单元格上的例程
- kubernetes - 可以在不同的命名空间中设置 Kubernetes 监控
- python - “CondaVerificationError:找不到路径'.../iTerm.app'。” 创建 conda 环境时
- javascript - 移除元素的时间复杂度
- javascript - 如何更改 Material-ui React 表格中的表格单元格宽度
- php - 根据php中的下拉值将数据库值获取到多个文本框
- android - 如何在谷歌分析中添加指标“唯一屏幕视图/会话”
- html - 引导轮播控件在单击后保持白色
- ios - 通过 CNContact 从 iPhone 获取所有联系人列表时联系人图像未获取