Изменить URL адресной строки в приложении AJAX для соответствия текущему состоянию

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

Как люди справляются с поддержанием RESTfulness в приложениях AJAX?

4.08.2008 17:53:32
Он используется для отображения состояния ваших приложений, но не имеет ничего общего с «RESTfulness».
Mohamed 21.12.2011 18:21:44
window.history.pushState(null,'hi','page1?id=32')
Omu 16.06.2012 10:15:33
принятый ответ был написан 5 лет назад, и тем временем мы получили window.history.pushState, как и сказал @Omu. location.hash принес много проблем и лучше всего избегать этого.
pcarvalho 21.09.2013 20:01:17
Я отредактировал ответ, чтобы сделать подход pushState заметным.
jasonjwwilliams 19.03.2014 20:58:07
8 ОТВЕТОВ
РЕШЕНИЕ

Способ сделать это состоит в том, чтобы манипулировать, location.hashкогда обновления AJAX приводят к изменению состояния, которое вы хотели бы иметь дискретный URL. Например, если URL вашей страницы:

http://example.com/

Если функция на стороне клиента выполнила этот код:

// AJAX code to display the "foo" state goes here.

location.hash = 'foo';

Затем URL-адрес, отображаемый в браузере, будет обновлен до:

http://example.com/#foo

Это позволяет пользователям отмечать состояние страницы "foo" и использовать историю браузера для навигации между состояниями.

С этим механизмом вам нужно будет проанализировать хеш-часть URL на стороне клиента, используя JavaScript для создания и отображения соответствующего начального состояния, так как идентификаторы фрагмента (часть после #) не отправляются в сервер.

Плагин hashchange Бена Алмана делает последний легким, если вы используете jQuery.

116
20.06.2011 17:31:29
Похоже, ты прав. Это единственный подход. Это похоже на хорошее подробное объяснение вашего совета: < ajaxpatterns.org/Unique_URLs >
jasonjwwilliams 4.08.2008 18:04:29
@buymeasoda Спасибо за редактирование; Я не уверен, о чем я думал, когда писал эту часть.
Dave Ward 25.04.2011 02:40:46
Вау, этот ответ был очень полезным. Хотя примеры URL немного сбивают с толку, SO может автоматически заменять ссылки заголовками. Как насчет замены на что-то вроде example.com и example.com/#foo, чтобы мы могли видеть весь URL в открытом тексте.
Neil 20.06.2011 17:14:46
@Pascal Вы можете, но только в браузерах, которые поддерживают pushState в HTML5. Хорошая информация об этом здесь: diveintohtml5.info/history.html
Dave Ward 20.04.2012 04:46:24
В итоге я стал большим поклонником history.js, чтобы охватить основы совместимости браузеров github.com/andreasbernhard/history.js
jocull 11.02.2013 16:01:56

Посмотрите на такие сайты, как book.cakephp.org. Этот сайт меняет URL без использования хеша и использует AJAX. Я не уверен, как это происходит, но я пытался понять это. Если кто-нибудь знает, дайте мне знать.

Также github.com при просмотре навигации по определенному проекту.

18
13.02.2011 19:54:34
Я заметил это с GitHub неделю или около того назад. Как же они это делают? Должен вернуться и проверить.
Drew Noakes 14.02.2011 01:46:29
Кажется, они используют функцию JavaScript pushState (). Это добавляет к истории вашего браузера. Посмотри на это; это довольно интересно и круто.
daniel.wright 2.03.2011 03:04:21
Спасибо за это, это было именно то, что я искал. Я задавался вопросом, как Github сделал это. Сначала я думал, что это должно быть перезагрузка, но были только запросы AJAX. В Opera это действительно перезагрузило страницу.
kamranicus 29.04.2011 15:12:20
Подобная техника используется fb при навигации по страницам разных групп. У вас есть левый столбец навигации, в котором упоминаются разные группы. Когда вы нажимаете на определенное имя группы, URL-адрес изменяется, и вместе с URL-адресом изменяется только содержимое главной панели содержимого (без хэша). Поэтому, когда пользователь перезагружает страницу, он не перенаправляется на домашнюю страницу, а на страницу групп.
Madeyedexter 19.07.2013 15:12:46

Вряд ли писатель захочет перезагрузить или перенаправить своего посетителя при использовании Ajax. Но почему бы не использовать HTML5 pushState/ replaceState?

Вы сможете изменять адресную строку столько раз, сколько захотите. Получите естественный вид URL с AJAX.

Проверьте код на моем последнем проекте: http://iesus.se/

17
24.06.2016 23:05:18

Это похоже на то, что сказал Кевин. У вас может быть состояние клиента как некоторый объект javascript, и когда вы хотите сохранить состояние, вы сериализуете объект (используя кодировку JSON и base64). Затем вы можете установить фрагмент href для этой строки.

var encodedState = base64(json(state));
var newLocation = oldLocationWithoutFragment + "#" + encodedState;

document.location = newLocation; // adds new entry in browser history
document.location.replace(newLocation); // replaces current entry in browser history

Первый способ будет рассматривать новое состояние как новое местоположение (поэтому кнопка «Назад» перенесет их в предыдущее место). Последнее нет.

11
4.08.2008 18:06:37
Есть ли способ добавить запись в историю закладок, не обновляя страницу? Установка местоположения (как в первом примере) приведет к обновлению, не так ли?
Drew Noakes 22.09.2010 10:42:16
выполнение document.location.replace также перенаправит браузер на этот URL (только что попробовал его в консоли Chrome)
Omu 16.06.2012 10:06:14

SWFAddress работает в проектах Flash и Javascript и позволяет создавать закладки для URL-адресов (используя метод хэширования, упомянутый выше), а также предоставляет поддержку кнопки «назад».

http://www.asual.com/swfaddress/

3
1.09.2008 13:43:36

Метод window.location.hash является предпочтительным способом ведения дел. Для объяснения того, как это сделать, Ajax Patterns - Уникальные URL .

YUI имеет реализацию этого шаблона в виде модуля, который включает в себя определенные обходные пути IE для работы кнопки «Назад» наряду с перезаписью адреса с использованием хэша. Диспетчер истории браузера YUI .

Другие платформы также имеют аналогичные реализации. Важным моментом является то, что если вы хотите, чтобы история работала вместе с перезаписью адреса, различным браузерам нужны разные способы обработки. (Это подробно описано в первой статье.)

IE нужен хак на основе iframe, где Firefox будет создавать двойную историю, используя тот же метод.

3
22.09.2010 10:00:25

Если OP или другие пользователи все еще ищут способ изменить историю браузера, чтобы включить состояние, использование pushState и replaceState, как это предлагает IESUS, является «правильным» способом сделать это сейчас. Это главное преимущество по сравнению с location.hash, похоже, в том, что он создает реальные URL, а не просто хэши. Если история браузера, использующая хэши, сохраняется, а затем возвращается с отключенным JavaScript, приложение не будет работать, поскольку хэши не отправляются на сервер. Однако, если pushState был использован, весь маршрут будет отправлен на сервер, который вы затем сможете построить, чтобы соответствующим образом реагировать на маршруты. Я видел пример, когда одни и те же шаблоны усов использовались как на стороне сервера, так и на стороне клиента. Если бы на клиенте был включен javascript, он получал бы быстрые ответы, избегая обращения к серверу в обоих направлениях, но без javascript приложение работало бы отлично. Таким образом, приложение может изящно ухудшаться при отсутствии javascript.

Кроме того, я полагаю, что есть какая-то инфраструктура с таким именем, как history.js. Для браузеров, которые поддерживают HTML5, он использует pushState, но если браузер не поддерживает это, он автоматически возвращается к использованию хэшей.

3
23.06.2011 09:20:36

Проверьте, находится ли пользователь на странице, когда вы нажимаете на строку URL, javascript говорит, что вы находитесь вне страницы. Если вы измените строку URL и нажмете «ENTER» с символом «#» внутри, то вы снова перейдете на страницу, не щелкая мышью курсор на странице вручную, тогда команда события keyboad (document.onkeypress) из javascript будет быть в состоянии проверить, если он входит и активировать JavaScript для перенаправления. Вы можете проверить, находится ли пользователь на странице с помощью window.onfocus, и проверить, работает ли он с помощью window.onblur.

Да, это возможно.

;)

2
13.10.2010 23:18:50
Это элегантный способ изменить страницу, когда пользователь редактирует строку URL с символом #.
Marcelo 13.10.2010 23:23:27