Изменение URL-адреса в браузере без загрузки новой страницы с помощью JavaScript

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

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

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

14 ответов


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

основная идея состоит в том, чтобы установить window.location.hash свойство для значения, содержащего любую необходимую информацию о состоянии, затем либо используйте


С 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-адрес без добавления записи в список кнопки "назад", используйте .


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

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

[Edit in 2011: так как я написал этот ответ в 2008 году, больше информации пришло свет относительно техника в HTML5 это позволяет изменять URL-адрес, если он из того же источника]


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

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

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

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


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

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, и свойство state события содержит копию объекта state записи журнала.

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

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

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


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


фотогалерея Facebook делает это с помощью хэша #в 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

обратите внимание на hash-bang (#!) сразу же после этого новый URL.


есть место.hash= 'text' в http://probablyinteractive.com/url-hunter


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

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


мой код:

//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;
    });
});

вот и все :)


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

так что, скажем, пользователь находится на странице: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. Поэтому, когда div используется для обработки различных методов сверхурочной работы, эти данные не сохраняются для каждого состояния истории.


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

location.hash="myValue";

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

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

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

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

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