Оновлення 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.