Как я могу использовать JavaScript, чтобы обнаружить, если я нахожусь на кэшированной странице
Я хочу отображать из кэша в течение длительного времени, и я хочу немного другое поведение при отображении страницы по сравнению с загрузкой страницы из кэша. Есть ли простой способ определить это с помощью JavaScript?
8 ответов
Один из способов сделать это - включить время, когда страница была сгенерирована на странице, а затем использовать некоторый JavaScript, чтобы сравнить местное время со временем, когда страница была сгенерирована. Если время отличается на пороговое значение, то страница поступила из кэша. Проблема заключается в том, что если на клиентском компьютере установлено неправильное время, хотя вы можете обойти это, заставив клиента включить свое текущее системное время в запрос на создание страницы, а затем отправить это значение обратно клиенту.
Я начал с ответа, который дал "Даниэль" выше, но боюсь, что из-за медленного соединения у меня могут возникнуть проблемы с задержкой.
Вот решение, которое в конечном итоге сработало для меня. На стороне сервера я добавляю cookie refCount и устанавливаю его значение равным 0. При загрузке документа в java-скрипте я сначала проверяю refCount, а затем увеличиваю его. При проверке, если refCount больше 1, я знаю, что страница кэшируется. Так что для этого работает как шарм.
Спасибо, ребята, что привели меня к этому решению.
С новой спецификацией Resource Timing Level 2 вы можете использовать свойство передачи размера, чтобы проверить, загружена ли страница из кэша:
var isCached = performance.getEntriesByType("navigation")[0].transferSize === 0;
- Spec: https://www.w3.org/TR/resource-timing-2/
- Поддержка браузера: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming
- обратите внимание, что на момент написания, это показывает, что Safari не поддерживает, в то время как на самом деле последняя версия поддерживает.
Пока этому вопросу уже 4 года. Я думал, что добавлю свои 2 цента, используя jQuery и плагин History.
$(document).ready(function()
{
$('body').append('<div class="is_cached"></div>');
});
History.Adapter.bind(window,'statechange',function(){
if($('.is_cached').length >= 1)
{
alert('this page is cached');
}
});
Когда документ впервые загружен. Добавлен новый div.is_cached. Нет совместимого способа выполнения JavaScript при загрузке кэшированной страницы, но вы можете отслеживать изменения в истории. Когда история изменяется и div.is_cached существует, тогда пользователь просматривает кэшированную страницу.
Пытатьсяperformance.getEntriesByType('resource')
API, он вернет время каждого этапа и его значение для всех сетевых ресурсов следующим образом:
На скриншоте выше показано, что мы получили файл с именемhttps://www.google.com/xjs/_/js/k=xjs...
общее количество загрузок 925 (мс), ее типscript
.
Таким образом, мы можем определить, попали ли некоторые файлы в кэш, основываясь на ихduration
и фильтрtype
илиname
мы хотим сосредоточиться:
const includeFileTypes = [
'script',
// 'css',
// 'img',
]
const includeFileNames = [
'yourTargteFileName.js',
]
function getFileNameFromURL(url) {
return url?.match(/[^\\/]+(?!.*\/)/)?.[0]
}
const getResourceTiming = () => {
const resources = performance
.getEntriesByType('resource')
.filter(({ initiatorType }) => {
return includeFileTypes.includes(initiatorType)
})
// .filter(({ name }) => {
// return includeFileNames.includes(getFileNameFromURL(name))
// });
return resources.map(
({
name,
// redirectEnd,
// redirectStart,
// domainLookupEnd,
// domainLookupStart,
// connectEnd,
// connectStart,
// secureConnectionStart,
responseEnd,
responseStart,
// fetchStart,
// requestStart,
startTime,
duration,
}) => ({
name: getFileNameFromURL(name),
startTime: parseInt(startTime),
endTime: parseInt(responseEnd - responseStart),
duration: parseInt(duration),
}),
);
};
function getHitCacheFiles(allTargetResources) {
return allTargetResources?.filter(({name, duration}) => {
if (duration < 20) {
console.log(`Hit Cache: ${name}`)
return true
} else {
console.log(`Not Hit Cache: ${name}`)
return false
}
})
}
const allTargetResources = getResourceTiming()
console.table(getHitCacheFiles(allTargetResources))
ДЕМО
Он напечатает:
Он также соответствует панели DevTool Network:
getEntriesByType('resource')
использование проще, чемtransferSize
, ему не нужен дополнительный HTTP-заголовокTiming-Allow-Origin: https://yoursite.com
Используя XmlHttpRequest, вы можете открыть текущую страницу, а затем изучить http-заголовки ответа.
Лучше всего просто выполнить запрос HEAD, а затем изучить заголовки.
Некоторые примеры этого можно посмотреть на http://www.jibbering.com/2002/4/httprequest.html
Не напрямую, некоторые браузеры могут иметь некоторые собственные команды для этого.
Существует обходной путь, который будет делать то, что вы хотите. Используйте куки для хранения timestamp
первого посещения, а затем используйте META HTTP-EQUIV, чтобы установить продолжительность кэширования файла (cacheLength
). Если текущее время находится в пределах периода времени с timestamp
в timestamp+cacheLength
тогда относитесь как к загруженным из кеша. После истечения срока действия кеша сбросьте время использования куки.
- Добавляйте уникальные данные на страницу на сервере при создании. Например, случайное число или время создания:
window.rand = {{ rand() }}
- Используйте локальное хранилище, чтобы сохранить URL-адрес с номером и сравнить его позже, если необходимо:
reloadIfCached() {
var cached = localStorage.getItem(window.location.href) == window.rand;
if (cached) {
window.location.reload();
}
localStorage.setItem(window.location.href, window.rand);
}