Оновлення Ajax, кнопки повернення та DOM


113

Якщо javascript змінює DOM на сторінці A, користувач переходить на сторінку B, а потім натискає кнопку назад, щоб повернутися на сторінку A. Усі зміни DOM сторінки A втрачаються, а користувачеві надається версія, спочатку отримана з сервера.

Це працює таким чином на stackoverflow, reddit та багатьох інших популярних веб-сайтах. (спробуйте додати тестове зауваження до цього питання, потім перейдіть на іншу сторінку та натисніть кнопку назад, щоб повернутися - ваш коментар буде "пропав")

Це має сенс, але деякі веб-сайти (apple.com, basecamphq.com тощо) якимось чином змушують браузер обслуговувати останній стан сторінки. (перейдіть за посиланням http://www.apple.com/ca/search/?q=ipod , натисніть посилання Скажіть на завантаження вгорі, а потім натисніть кнопку "назад" - усі оновлення DOM будуть збережені)

звідки випливає неузгодженість?


Цікаво, що Apple пам’ятає стан, не змінюючи хеш .. хммм
— Джеймс

Apple схоже, що вони просто маніпулюють кешуванням відповідей
— BigBlondeViking

Як вже говорили інші, це не щось пов'язане з javascript або ajax. Вам слід видалити ці теги, щоб отримати правильні відповіді.
— BYK

Приклад Apple - поганий. Якщо ви підписали контракт на пошукову зону [колишні продукти], натисніть посилання, а потім натисніть назад, DOM не зберігається. ви шукаєте хеш-рішення, яке багато хто запропонував.
— BigBlondeViking

Коли я натискаю кнопку назад, Apple не пам’ятає, на якій сторінці результатів пошуку я взагалі був. Використання IE7. Вам потрібен хеш-розчин. Дивіться: Facebook.
— Джош Стодола

Відповіді:


106

Одна відповідь: Окрім іншого, події завантаження призводять до недійсності кешу назад / вперед .

Деякі веб-переглядачі зберігають поточний стан всієї веб-сторінки у так званому «bfcache» або «кеші сторінок». Це дозволяє їм дуже швидко відтворювати сторінку під час навігації за допомогою кнопок назад і вперед, а також зберігає стан DOM та всіх змінних JavaScript. Однак, коли на сторінці містяться події завантаження, ці події потенційно можуть перевести її у нефункціональний стан, і тому сторінка не зберігається у bfcache та повинна бути перезавантажена (але може бути завантажена із стандартного кешу) та повторно виводиться з нуля, включаючи запуск усіх оброблювачів завантаження. Повертаючись на сторінку через bfcache, DOM зберігається у попередньому стані, не потребуючи запуску оброблювачів завантаження (оскільки сторінка вже завантажена).

Зауважте, що поведінка bfcache відрізняється від стандартного кешу браузера щодо Cache-Control та інших заголовків HTTP. У багатьох випадках браузери кешуватимуть сторінку в bfcache, навіть якщо в іншому випадку вона не зберігатиме її у стандартному кеші.

jQuery автоматично приєднує подію до вивантаження, тому, на жаль, використання jQuery позбавить вашу сторінку зберігатись у bfcache для збереження DOM та швидкого повернення / перемотування вперед. [Оновлення: це було виправлено у jQuery 1.4, так що воно стосується лише IE]


3
ти це повністю прибив. обидва, reddit і stackoverflow використовують jquery, тоді як basecamp та apple використовують прототипи. це майже все пояснює.
— lubos hasko

+1 цікаво (не перехресний браузер), питання набагато інше, ніж коли воно почалося ...
— BigBlondeViking

1
це, мабуть, крос-браузер, тому що я можу відтворити його і на своєму Internet Explorer. Я впевнений, що кожен веб-браузер із увімкненим JavaScript повинен у будь-якому разі стикатися з цією проблемою. але це справді безлад, коли ви думаєте про це, кнопка "Назад" завжди повинна приводити людей на сторінку, яку вони бачили останніми з усіма оновленнями DOM, стан javascript тощо. Розробники не повинні порушувати це, роблячи щось під час події завантаження та якщо це так, веб-браузери не повинні намагатися виправити проблему, не використовуючи bfcache взагалі. вся подія розвантаження - одна велика жарт. Я впевнений, що 99% часу використовується для виправлення витоків пам'яті.
— lubos hasko

1
Зокрема, протікає пам'ять IE. :) Подія завантаження jQuery також може виправити (абсолютно не пов'язану) помилку у Firefox 2. Але це не потрібно для інших браузерів. dev.jquery.com/ticket/3015 Я вважаю, що я чув про інші види використання для завантаження, як відстеження вихідних кліків або збереження стану webapp, але я ніколи не мав причин використовувати його сам, і якщо розробники хочуть зробити їх сайти повільніше і болючіше для своїх користувачів (я ненавиджу, як повернення до редагування сторінок коментарів скидає стан коментованого згорнутого), це їх прерогатива.
— Майлз

1
Подія вивантаження додається лише для IE, а не для firefox та chrome. Остання версія сафарі зберігає домову державу, без того, щоб розробник нічого не робив.
— Девід

15

Я намагався змусити Chrome поводитись так, як це робить Safari, і єдиний спосіб, який я знайшов, працює - це встановити Cache-control: no-storeзаголовки. Це змушує браузер повторно забирати сторінку з сервера, коли користувач натискає кнопку назад. Не ідеально, але краще, ніж показувати застарілу сторінку.


5
Це правильна відповідь на вихідне запитання. Якщо ви хочете змусити перезавантажити сервер на кнопці "назад", використовуйте кеш-контроль "no-store, no-cache, must revalidate". Chrome не потребує зберігання, а IE хоче повторне оновлення. Для інших браузерів (і w3c) недостатньо кеш-пам'яті.
— woens

3

Facebook запам'ятовує стан сторінки, змінюючи ідентифікатор хешу в URL-адресі для запитів ajax. Ці зміни записуються в історію браузера, тому коли користувач натискає кнопку назад, хеш змінюється на те, що було раніше. Тож мається на увазі, що вам знадобиться Javascript, щоб відстежувати ідентифікатор has і реагувати, коли він змінюється браузером. У Andreas Blixt доступний сценарій хеш-моніторингу .


на сьогоднішній день це не вмирає, це не може сказати мені, що робить зараз facebook
— Ravinder Payal

3

Це не має нічого спільного з символом хеша (#).

Якщо ви перевірите HTTP-заголовки Apple, це просто кешування сторінки.


Приклад Apple поганий, вони не "зберігають" стан сторінки, його припущення, що DOM зберігає це неправильно
— BigBlondeViking

2

Використання ідентифікатора хешу / фрагмента URL - досить поширений спосіб підключення / запам'ятовування стану у веб-програмі, яка спирається на оновлення Ajax та DOM.

Ознайомтеся з проектом « Справді проста історія », щоб отримати деякі ідеї. Можливо відстежувати URL для змін у хеші, і rsh робить це, враховуючи відмінності браузера.


1

Для всіх, хто Railsзіткнувся з проблемами, і це - ваше питання не bfcache (я думав, що це було) - це turbolinksдорогоцінний камінь. Ось як її видалити.

Сподіваємось, це заощадить вам якийсь час і вдарить головою об стіну.


0

Що ви шукаєте, це певний тип управління хешем URL-адрес. # В URL-адресі призначений лише для клієнта.

Коли ви змінюєте стан спинки за допомогою JS, то ви оновлюєте дані у # URL-адресі.

Також ви додаєте певний тип опитування, який відстежує, чи змінився хеш, і завантажує стан сторінки, виходячи з нових даних у хеші.

Погляньте на це:

http://ajaxpatterns.org/Unique_URLs


3
це не має нічого спільного з символом хеша.
— Лука Маттейс

3
Ви помиляєтесь, він шукає найпоширеніший спосіб збереження стану сторінки в рішенні AJAX.
— BigBlondeViking
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.