Измените URL в браузере, не загружая новую страницу с помощью JavaScript - PullRequest
293 голосов
/ 26 сентября 2008

Как бы у меня было действие JavaScript , которое может оказать некоторое влияние на текущую страницу, но также изменить URL-адрес в браузере, поэтому, если пользователь нажимает перезагрузить или добавить в закладки новый URL-адрес?

Было бы также неплохо, если бы кнопка «Назад» перезагрузила бы исходный URL.

Я пытаюсь записать состояние JavaScript в URL.

Ответы [ 14 ]

187 голосов
/ 26 сентября 2008

Если вы хотите, чтобы он работал в браузерах, которые еще не поддерживают history.pushState и history.popState, «старый» способ - установить идентификатор фрагмента, что не приведет к перезагрузке страницы.

Основная идея состоит в том, чтобы установить для свойства window.location.hash значение, которое содержит любую необходимую информацию о состоянии, затем либо использовать событие window.onhashchange , либо для более старых браузеров, которые не поддерживают onhashchange (IE <8, Firefox <3.6), периодически проверяйте, изменился ли хэш (например, с использованием <code>setInterval), и обновляйте страницу. Вам также необходимо проверить значение хеш-значения при загрузке страницы, чтобы настроить исходное содержимое.

Если вы используете jQuery, есть плагин hashchange , который будет использовать любой метод, поддерживаемый браузером. Я уверен, что есть плагины и для других библиотек.

Одна вещь, о которой следует быть осторожным, это столкновение с идентификаторами на странице, потому что браузер будет прокручивать к любому элементу с совпадающим идентификатором.

113 голосов
/ 19 ноября 2010

В HTML 5 используйте функцию history.pushState . Как пример:

<script type="text/javascript">
var stateObj = { foo: "bar" };
function change_my_url()
{
   history.pushState(stateObj, "page 2", "bar.html");
}
var link = document.getElementById('click');
link.addEventListener('click', change_my_url, false);
</script>

и href:

<a href="#" id='click'>Click to change url to bar.html</a>

Если вы хотите изменить URL-адрес без добавления записи в список кнопок «Назад», используйте history.replaceState.

37 голосов
/ 26 сентября 2008

window.location.href содержит текущий URL. Вы можете читать с него, добавлять к нему и заменять его, что может привести к перезагрузке страницы.

Если, как это звучит, вы хотите записать состояние javascript в URL, чтобы его можно было добавить в закладки, без перезагрузки страницы, добавьте его к текущему URL после # и получите фрагмент javascript, вызванный событием onload проанализируйте текущий URL-адрес, чтобы увидеть, содержит ли он сохраненное состояние.

Если вы используете? вместо # вы будете принудительно перезагружать страницу, но, поскольку вы будете анализировать сохраненное состояние при загрузке, это может на самом деле не быть проблемой; и это заставит кнопки вперед и назад работать правильно.

22 голосов
/ 26 сентября 2008

Я бы сильно подозревал, что это невозможно, потому что это было бы невероятной проблемой безопасности, если бы это было так. Например, я мог бы сделать страницу, которая выглядела как страница входа в банк, и сделать URL-адрес в адресной строке похожим на точно так же, как реальный банк !

Возможно, если вы объясните, почему вы хотите это сделать, люди смогут предложить альтернативные подходы ...

[Редактировать в 2011 году. С тех пор, как я написал этот ответ в 2008 году, появилась дополнительная информация о методе HTML5 , который позволяет изменять URL-адрес, если он принадлежит одному и тому же происхождения]

8 голосов
/ 26 сентября 2008

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

Единственный надежный способ изменить URL-адрес без изменения страниц - использовать внутреннюю ссылку или хэш. например: http://site.com/page.html становится http://site.com/page.html#item1. Эта техника часто используется в Hijax (AJAX + сохранить историю).

При этом я часто просто использую ссылки для действий с хешем в качестве href, затем добавляю события click с помощью jquery, которые используют запрошенный хеш для определения и делегирования действия.

Надеюсь, это поставит вас на правильный путь.

7 голосов
/ 09 октября 2013

jQuery имеет отличный плагин для изменения URL браузера, называемый jQuery-pusher .

JavaScript pushState и jQuery могут использоваться вместе, например:

history.pushState(null, null, $(this).attr('href'));

Пример:

$('a').click(function (event) {

  // Prevent default click action
  event.preventDefault();     

  // Detect if pushState is available
  if(history.pushState) {
    history.pushState(null, null, $(this).attr('href'));
  }
  return false;
});


Использование только JavaScript history.pushState(), который изменяет реферер, который используется в заголовке HTTP для объектов XMLHttpRequest, созданных после изменения состояния.

Пример:

window.history.pushState("object", "Your New Title", "/new-url");

Метод pushState ():

pushState() принимает три параметра: объект состояния, заголовок (который в настоящее время игнорируется) и (необязательно) URL-адрес. Давайте рассмотрим каждый из этих трех параметров более подробно:

  1. объект состояния - Объект состояния - это объект JavaScript, связанный с новой записью истории, созданной pushState(). Всякий раз, когда пользователь переходит к новому состоянию, запускается событие popstate, а свойство состояния события содержит копию объекта состояния записи истории.

    Объект состояния может быть любым, что может быть сериализовано. Поскольку Firefox сохраняет объекты состояния на диск пользователя, чтобы их можно было восстановить после того, как пользователь перезапустил свой браузер, мы накладываем ограничение размера в 640 тыс. Символов на сериализованное представление объекта состояния. Если вы передадите объект состояния, сериализованное представление которого больше этого, в pushState(), метод сгенерирует исключение. Если вам нужно больше места, чем это, вам рекомендуется использовать sessionStorage и / или localStorage.

  2. title - Firefox в настоящее время игнорирует этот параметр, хотя может использовать его в будущем. Передача пустой строки здесь должна быть безопасной от будущих изменений метода. Кроме того, вы можете передать короткий заголовок для штата, в который вы переходите.

  3. URL - URL-адрес новой записи истории задается этим параметром. Обратите внимание, что браузер не будет пытаться загрузить этот URL после вызова pushState(), но он может попытаться загрузить этот URL позже, например, после того, как пользователь перезапустит свой браузер. Новый URL не обязательно должен быть абсолютным; если он относительный, он разрешается относительно текущего URL. Новый URL должен иметь то же происхождение, что и текущий URL; в противном случае pushState() выдаст исключение. Этот параметр является необязательным; если он не указан, ему присваивается текущий URL документа.

4 голосов
/ 26 сентября 2008

Существует компонент Yahoo YUI (Диспетчер истории браузера), который может справиться с этим: http://developer.yahoo.com/yui/history/

3 голосов
/ 11 января 2011

Фотогалерея Facebook делает это с помощью #hash в URL. Вот несколько примеров URL:

Прежде чем нажать «Далее»:

/photo.php?fbid=496429237507&set=a.218088072507.133423.681812507&pid=5887027&id=681812507

После нажатия «Далее»:

/photo.php?fbid=496429237507&set=a.218088072507.133423.681812507&pid=5887027&id=681812507#!/photo.php?fbid=496435457507&set=a.218088072507.133423.681812507&pid=5887085&id=681812507

Обратите внимание на хэш-удар (#!), За которым сразу следует новый URL.

2 голосов
/ 26 апреля 2018

Что работает для меня, это - history.replaceState() функция, которая выглядит следующим образом -

history.replaceState(data,"Title of page"[,'url-of-the-page']);

Это не перезагрузит страницу, вы можете использовать ее с событием javascript

2 голосов
/ 20 апреля 2011

Есть плагин jquery http://www.asual.com/jquery/address/

Я думаю, это то, что вам нужно.

...