Измените URL-адрес в браузере, не загружая новую страницу с помощью JavaScript.

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

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

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

Ответ 1

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

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

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

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

Ответ 2

С 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.

Ответ 3

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

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

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

Ответ 4

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

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

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

Ответ 5

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

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

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

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

Ответ 6

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. Давайте рассмотрим каждый из этих трех параметров более подробно:

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

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

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

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

Ответ 7

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

Ответ 8

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

Перед нажатием "next":

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

После нажатия "next":

/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-адрес.

Ответ 11

мой код:

//change address bar
function setLocation(curLoc){
    try {
        history.pushState(null, null, curLoc);
        return false;
    } catch(e) {}
        location.hash = '#' + curLoc;
}

и действие:

setLocation('http://example.com/your-url-here');

и пример

$(document).ready(function(){
    $('nav li a').on('click', function(){
        if($(this).hasClass('active')) {

        } else {
            setLocation($(this).attr('href'));
        }
            return false;
    });
});

Что все:)

Ответ 12

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

Итак, позвольте сказать, что пользователь находится на странице: http://domain.com/site/page.html Тогда браузер может позволить мне сделать location.append = new.html и страница станет: http://domain.com/site/page.htmlnew.html, и браузер не изменит ее.

Или просто позвольте человеку изменить параметр get, поэтому пусть location.get = me=1&page=1.

Итак, исходная страница становится http://domain.com/site/page.html?me=1&page=1, и она не обновляется.

Проблема С# заключается в том, что данные не кэшируются (по крайней мере, я так не думаю), когда хеш изменен. Таким образом, каждый раз, когда загружается новая страница, кнопки обратной и прямой на странице Ajax могут кешировать данные и не тратить время на повторную загрузку данных.

Из того, что я видел, история Yahoo уже загружает все данные сразу. Кажется, он не выполняет никаких запросов Ajax. Поэтому, когда a div используется для обработки разного времени работы метода, эти данные не сохраняются для каждого состояния истории.

Ответ 13

У меня был успех:

location.hash="myValue";

Он просто добавляет #myValue к текущему URL. Если вам нужно вызвать событие на странице Load, вы можете использовать тот же location.hash, чтобы проверить соответствующее значение. Не забудьте удалить # из значения, возвращаемого location.hash например.

var articleId = window.location.hash.replace("#","");