Как я могу использовать JavaScript, чтобы обнаружить, если я нахожусь на кэшированной странице

Я хочу отображать из кэша в течение длительного времени, и я хочу немного другое поведение при отображении страницы по сравнению с загрузкой страницы из кэша. Есть ли простой способ определить это с помощью JavaScript?

8 ответов

Решение

Один из способов сделать это - включить время, когда страница была сгенерирована на странице, а затем использовать некоторый JavaScript, чтобы сравнить местное время со временем, когда страница была сгенерирована. Если время отличается на пороговое значение, то страница поступила из кэша. Проблема заключается в том, что если на клиентском компьютере установлено неправильное время, хотя вы можете обойти это, заставив клиента включить свое текущее системное время в запрос на создание страницы, а затем отправить это значение обратно клиенту.

Я начал с ответа, который дал "Даниэль" выше, но боюсь, что из-за медленного соединения у меня могут возникнуть проблемы с задержкой.

Вот решение, которое в конечном итоге сработало для меня. На стороне сервера я добавляю cookie refCount и устанавливаю его значение равным 0. При загрузке документа в java-скрипте я сначала проверяю refCount, а затем увеличиваю его. При проверке, если refCount больше 1, я знаю, что страница кэшируется. Так что для этого работает как шарм.

Спасибо, ребята, что привели меня к этому решению.

С новой спецификацией Resource Timing Level 2 вы можете использовать свойство передачи размера, чтобы проверить, загружена ли страница из кэша:

var isCached = performance.getEntriesByType("navigation")[0].transferSize === 0;

Пока этому вопросу уже 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

Ссылки: TransferSize#cross-origin_content_size_information

Используя XmlHttpRequest, вы можете открыть текущую страницу, а затем изучить http-заголовки ответа.

Лучше всего просто выполнить запрос HEAD, а затем изучить заголовки.

Некоторые примеры этого можно посмотреть на http://www.jibbering.com/2002/4/httprequest.html

Не напрямую, некоторые браузеры могут иметь некоторые собственные команды для этого.

Существует обходной путь, который будет делать то, что вы хотите. Используйте куки для хранения timestamp первого посещения, а затем используйте META HTTP-EQUIV, чтобы установить продолжительность кэширования файла (cacheLength). Если текущее время находится в пределах периода времени с timestamp в timestamp+cacheLength тогда относитесь как к загруженным из кеша. После истечения срока действия кеша сбросьте время использования куки.

  1. Добавляйте уникальные данные на страницу на сервере при создании. Например, случайное число или время создания:
       window.rand = {{ rand() }} 
  1. Используйте локальное хранилище, чтобы сохранить URL-адрес с номером и сравнить его позже, если необходимо:
       reloadIfCached() {
            var cached = localStorage.getItem(window.location.href) == window.rand;
            if (cached) {
                window.location.reload();
            }
            localStorage.setItem(window.location.href, window.rand);
       }
Другие вопросы по тегам