Изначально это было опубликовано на моем собственном сайте.
Когда я писал о стратегии лжи, которую я добавил на adactio.com, я закончил с этой мыслью:
Чего бы мне действительно хотелось, так это какого-нибудь способа узнать — на стороне клиента — была ли загруженная в данный момент страница из кеша или из сети. Затем я мог бы добавить какой-нибудь элемент интерфейса, говорящий: «Эй, эта страница может быть устаревшей — нажмите здесь, если хотите проверить наличие более свежей версии».
Trys услышал мою просьбу и придумал очень хитрую технику для изменения HTML-кода страницы, когда она помещается в кеш.
Это функция, которая считывает поток тела ответа и возвращает новый поток. При чтении потока он ищет коды символов, которые составляют:
<html
. Если он их находит, он использует атрибутdata-cached
.
Хороший!
Но потом я обсуждал этот вопрос с Тантеком и Аароном поздно ночью после Indie Web Camp Düsseldorf. Я понял, что у меня может быть другое потенциальное решение, которое вообще не задействует сервис-воркера.
Предупреждение: это будет работать только для страниц, которые имеют какую-то генерацию на стороне сервера. Это не будет работать для статических сайтов.
В моем случае страницы генерируются PHP. Я не выполняю поиск в базе данных каждый раз, когда вы запрашиваете страницу — например, у меня есть кеш сообщений на стороне сервера — но для каждого запроса выполняется небольшая сборка: получить заголовок отсюда; получить основной контент оттуда; получить нижний колонтитул; поместите их все вместе на одну страницу и подавайте ее.
Это означает, что я могу добавить временную метку на страницу (используя PHP). Я могу отметить момент, когда он был подан. Затем я могу использовать JavaScript на стороне клиента, чтобы сравнить эту метку времени с текущим временем.
Я опубликовал код как сущность.
В элементе script
на каждой странице у меня есть немного кода:
var serverTimestamp = <?php echo time(); ?>;
Теперь переменная JavaScript serverTimestamp
содержит отметку времени создания страницы. Когда страница помещается в кеш, это не изменится. Это число должно быть количеством секунд с 1 января 1970 года в часовом поясе UTC (это часовой пояс моего сервера).
Начиная с объекта JavaScript Date
, я использую множество методов, таких как toUTCString()
и getTime()
, чтобы получить переменную с именем clientTimestamp
. Это даст текущее количество секунд с 1 января 1970 года, независимо от того, поступает ли страница с сервера или из кеша.
var localDate = new Date();
var localUTCString = localDate.toUTCString();
var UTCDate = new Date(localUTCString);
var clientTimestamp = UTCDate.getTime() / 1000;
Затем я сравниваю их и смотрю, есть ли расхождение более чем на пять минут:
if (clientTimestamp - serverTimestamp > (60 * 5))
Если да, то я добавляю на страницу некоторую разметку, сообщая читателю, что эта страница может быть устаревшей:
document.querySelector('main').insertAdjacentHTML('afterbegin',`
<p class="feedback">
<button onclick="this.parentNode.remove()">dismiss</button>
This page might be out of date. You can try <a href="javascript:window.location=window.location.href">refreshing</a>.
</p>
`);
У читателя есть возможность обновить страницу или отклонить сообщение.
Это ни в коем случае не надежно. Если часы компьютера посетителя настроены странно, то сравнение может каждый раз возвращать ложное срабатывание. Тем не менее, я думал, что использование UTC может быть более безопасным.
В целом, я думаю, что это довольно хороший метод для определения того, обслуживается ли страница из кеша. Помните, что цель здесь не в том, чтобы определить, находится ли пользователь в автономном режиме — для этого есть navigator.onLine
.
Результат таков: если вы зайдете на мой сайт с плохим подключением к Интернету (ли-фай), то через три секунды вам может быть предоставлена кешированная версия запрашиваемой вами страницы (если вы посещали эту страницу ранее). Если это произойдет, теперь вам также будет представлено небольшое сообщение о том, что страница не свежая. Тогда вам решать, хотите ли вы попробовать еще раз.
Мне нравится, как это возвращает контроль в руки пользователя.
Изначально это было опубликовано на моем собственном сайте.