История pushState и страница кеширования

Как кэшировать страницу, загруженную через ajax, с URL-адресом pushState, чтобы избежать перезагрузки страницы с сервера? Например,

страница 1: /foo.html. нажмите кнопку, отправьте запрос AJAX, получите ответ и обновите страницу. История pushState как новая страница /bar.html.

   history.pushState({}, '','/bar.html');

На этом этапе мы хотим, чтобы браузер кешировал текущую страницу как /bar.html.

window.onpopstate = function(event) {
  // browser is not loading page automatically for back/forward
  if (event.state)
    location.reload();
};

При нажатии кнопки назад / вперед файл /bar.html должен быть загружен из кеша браузера. Но он снова загружается с сервера. Как этого добиться? то есть, пусть страница, обновленная с помощью ajax, обрабатывается как обычный GET /bar.html и кэшируется браузером. как?

Спасибо за любую подсказку. Дэйв


person Dave    schedule 18.05.2014    source источник
comment
«Как этого добиться?» - точно так же, как вы бы это сделали, если бы AJAX и pushState не были задействованы вообще.   -  person CBroe    schedule 18.05.2014
comment
как указать браузеру кэшировать его как новый URL-адрес? Спасибо.   -  person Dave    schedule 18.05.2014
comment
Вы просто делаете свой запрос AJAX еще раз, когда пользователь снова переходит к этой записи истории - и если вы реализовали правильное кеширование, тогда браузер будет брать данные из кеша, а не запрашивать их снова.   -  person CBroe    schedule 18.05.2014
comment
установить заголовок ответа Cache-Control: max-age = 86400. Браузер Chrome / FireFox не кеширует его. onpopstate: location.reload () всегда повторно запрашивает страницу с сервера.   -  person Dave    schedule 18.05.2014
comment
Ну, это вроде того, что location.reload() делает на самом деле ... но кто вообще сказал что-нибудь об использовании этого метода?   -  person CBroe    schedule 18.05.2014
comment
window.onpopstate = функция (событие) {если (event.state) location.reload (); }; Перезагрузить страницу для кнопки браузера назад / вперед. Как правильно это делать? Спасибо.   -  person Dave    schedule 18.05.2014
comment
И почему именно это вы сделали бы…?   -  person CBroe    schedule 18.05.2014
comment
Без onpopstate браузер не будет автоматически загружать страницу для перехода назад / вперед.   -  person Dave    schedule 18.05.2014
comment
При использовании History API вы должны управлять тем, какой контент будет отображаться, когда пользователь перемещается вперед и назад, это правильно. Но никто не заставляет вас делать это, перезагружая страницу ... Вы уже использовали AJAX для извлечения содержимого и последующего помещения его в DOM, верно? Итак, что мешает вам сделать именно это снова (и тем самым использовать кеш браузера, когда он поймет: «Эй, я уже загружал этот контент один раз раньше, поэтому я не здесь нужно сделать новый HTTP-запрос, но я могу ответить на этот AJAX-запрос, вынув данные из моего кеша »)…?   -  person CBroe    schedule 18.05.2014
comment
используя кеш браузера? Вы имеете в виду кеширование страниц в браузере или веб-хранилище в html 5? Если stateObject сохраняет ответ ajax, ему по-прежнему требуется базовая модель DOM для обновления. Где хранить базовый ДОМ? на самом деле нужно где-то хранить всю DOM после обновления ajax.   -  person Dave    schedule 18.05.2014
comment
"использовать кеш браузера?" - разве не в этом ваш вопрос? Я говорю о «нормальном» кеше браузера для HTTP-запросов (как и вы раньше, с заголовком Cache-Control и так далее). И DOM для контента, загруженного через AJAX, вы получите автоматически, когда сделаете этот запрос AJAX - снова ... так где же здесь настоящая проблема?   -  person CBroe    schedule 18.05.2014
comment
Я отредактировал сообщение и надеюсь, что вам будет легче разобраться в проблеме.   -  person Dave    schedule 18.05.2014
comment
Не совсем. А комментарий // browser is not loading page automatically for back/forward делает это еще более неясным - ну, разве не почему вы вообще используете History API? Если вы просто хотите, чтобы браузер загружал страницы «нормально» - тогда зачем использовать History API, зачем использовать AJAX…?   -  person CBroe    schedule 18.05.2014
comment
лучший способ - загрузить из кеша браузера, а не с сервера. Я не знаю, как сделать так, чтобы просмотр кешировался как обычная страница (GET).   -  person Dave    schedule 18.05.2014
comment
В основном путем установки соответствующих HTTP-заголовков, касающихся поведения кеша, поэтому проведите небольшое исследование по этому поводу.   -  person CBroe    schedule 18.05.2014
comment
@CBroe Я думаю, вы упускаете точку зрения Дэйва. Я задал аналогичный вопрос здесь: stackoverflow.com/questions/27356774/, я могу неправильно понять Дэйва.   -  person Hello World    schedule 08.12.2014


Ответы (1)


Если вы включите http-кеширование, добавив соответствующие заголовки в ваши ответы (Cache-Control, Expires, Last-Modified и т. Д.), Эти ответы будут сохранены в кеше. Кеша нет ни одного. Есть кеш сервера и нисходящие кеши (ISP, прокси, браузер). Один из них - кеш браузера.

Предположим, вы кешируете ответы. Имейте в виду, что http-ответ будет кэшироваться независимо от его типа содержимого (html, json и т. Д.). Итак, вы загружаете страницу A, затем щелкаете ссылку, которая обновляет страницу с помощью ajax и URL-адреса с историей api. Это страница B. Затем вы переходите на страницу C. Ответы A, B и C хранятся в кеше браузера. Но если вы вернетесь на страницу B, браузер не загрузит ее автоматически, поскольку вы использовали API истории для этого URL-адреса. Он просто обновляет URL-адрес и запускает событие popstate.

  1. Один из подходов - прослушать popstate и вручную выполнить тот же вызов ajax. Поскольку ответ B уже хранится в кеше браузера, он будет извлечен оттуда (если он не был изменен на сервере).
  2. Другой подход состоял бы в том, чтобы сохранить данные, полученные из ajax, в объекте с именем state и связать его с отправленным URL-адресом:

    state = { your_key: your_value }
    history.pushState(state, title, url)
    

    Затем на кнопке «Назад» перехватите событие popstate, получите связанный с ним объект состояния, получите доступ к своим данным и измените страницу.

    $(window).on('popstate', function(event) { 
       var state = event.originalEvent.state; 
       if (state) { 
          // use it to modify the page 
       }else{ 
          // ajax call to get the data 
       }
    });
    

    В этом случае, если состояние существует, вы фактически не используете кеш браузера для получения ответа.

Имейте в виду, что объект состояния хранится на диске клиента и имеет ограниченный размер. Таким образом, лучше хранить в объекте состояния ссылку на данные (например, идентификатор), а сами данные хранить в памяти. Это предполагает, что у вас есть приложение Signle Page, все страницы которого загружены с помощью ajax. (Обычная загрузка страницы очистит память вашего клиента)

person dimyG    schedule 26.01.2018
comment
что, если бы я на самом деле не выполнял ajax (или любой другой) вызов bar.html? - person Vijay Chavda; 14.06.2021