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

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

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

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

Это было бы так хорошо. Конечно, это будет ограничено модификациями в одном домене. Но некоторый клиентский контроль пути (а не только хеша) является логичным шагом сейчас, когда перезагрузка страницы является своего рода «последним средством» для многих приложений.

harpo 26.03.2010 20:25

Примерное хорошее использование pushState: for(i=1;i<50;i++){var txt = "..................................................";txt‌​=txt.slice(0,i)+"HTM‌​L5"+txt.slice(i,txt.‌​length);history.push‌​State({}, "html5", txt);}

Derek 朕會功夫 07.03.2012 07:34

пример этого эффекта в действии: dujour.com

Ben 31.08.2012 21:26

Пример этого эффекта: facebook.com (при открытии изображений в лайтбоксе)

user659025 07.11.2012 16:06

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

dewd 04.05.2014 12:49
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
301
5
300 329
14
Перейти к ответу Данный вопрос помечен как решенный

Ответы 14

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

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

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

Не было бы большой проблемы, если бы изменения, не связанные с перезагрузкой, были ограничены путем, строкой запроса и фрагментом - i.s. не авторитет (домен и тому подобное).

Ollie Saunders 16.06.2010 18:16
youtube.com/user/SilkyDKwan#p/u/2/gTfqaGYVfMg is a example that it is possible, try switching videos :)
Spidfire 20.08.2010 00:54

Вы можете изменить только location.hash (все после #), как отмечает Мэтью Чамли в принятом ответе.

Paul Dixon 20.08.2010 02:41

Ты используешь Фейсбук? Facebook изменяет URL-адрес перезагрузки без, используя history.pushState().

Derek 朕會功夫 07.03.2012 07:20

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

Dheeraj Thedijje 05.07.2014 12:02

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

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

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

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

Разве поисковые системы не игнорируют эти внутренние ссылки (хеши)? В моем сценарии я хочу, чтобы пауки тоже перехватывали эти ссылки.

Drew Noakes 10.05.2009 18:51

@Drew, насколько мне известно, поисковые системы не могут рассматривать часть страницы как отдельный результат.

Matthew Crumley 11.05.2009 18:48

Теперь есть предложение, чтобы поисковые системы видели хеши: googlewebmastercentral.blogspot.com/2009/10/…

LKM 09.10.2009 01:03

Вместо использования setInterval для проверки document.location.hash можно использовать событие hashchange, поскольку оно гораздо более распространено. Проверьте здесь, какие браузеры поддерживают каждый стандарт.. Мой текущий подход - использовать push / popState в браузерах, которые его поддерживают. На остальных я установил хеш и смотрю только hashchange в поддерживающих браузерах. Это оставляет IE <= 7 без поддержки истории, но с полезной постоянной ссылкой. Но кого волнует история IE <= 7?

Irae Carvalho 10.02.2011 01:25

Взгляните на эту демонстрацию использования window.location.hash: jsbin.com/ezopap/5#Hello%20World

ripper234 15.02.2012 21:22

Если вы ajax запрашиваете новую страницу и повторно реализуете тег javascript, который Google предоставляет вам для аналитики Google, не получит ли он информацию о хэштеге и не зарегистрирует это как новое посещение страницы?

gabeio 14.07.2012 00:58

@gabeDel Да, хотя я не думаю, что Analytics записывает хэш, поэтому у него будет тот же URL. Лучшим способом было бы вручную вызвать _trackPageview с «реальным» URL-адресом новой страницы.

Matthew Crumley 14.07.2012 07:26

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

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

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

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

Извините, но ваш ответ неверен. Да, вы можете изменить URL-адрес.

Derek 朕會功夫 07.03.2012 07:22

Да, вы можете использовать api истории html5, но это не кроссбраузерно, хотя вы можете использовать поли-заливку, которая будет использовать хеш-адреса.

Jethro Larson 28.03.2012 03:07

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

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

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

запись состояния javascript в URL-адрес - это именно то, что я пытаюсь сделать

Steven Noble 26.09.2008 03:39

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

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

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

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

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

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

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

Ответ принят как подходящий

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

Вы правы, в прошлый раз я экспериментировал с Chrome. Я только что пробовал с Firefox 3.6 на моем Ubuntu, это не сработало. Думаю, нам придется подождать, пока HTML5 не будет полностью поддерживаться в FF.

clu3 17.12.2010 10:35

Пример кода вырезан и вставлен из developer.mozilla.org/en/DOM/Manipulating_the_browser_histor‌ y. Что на самом деле затрудняет объяснение того, что означают foo и bar в данном случае.

mikemaccana 01.02.2011 14:45

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

Paul Dixon 01.02.2011 15:11

@Paul: да, в статье выше есть эта информация.

mikemaccana 01.02.2011 20:09

В момент публикации этого комментария он работает на Firefox Chrome и Safari. Хотя с мобильным сафари на ipad или iphone не повезло :(

Sid 04.06.2011 07:06

благодарю за ответ. Я думаю, что replaceState будет лучшим выбором: history.replaceState({"test":"test}, document.title, "bar.html");

Amin.Qarabaqi 02.05.2019 15:48

Я до сих пор не могу на 100% понять, какова / была первоначальная цель объекта состояния (после прочтения связанной статьи (статей). Как наилучшим образом использовать ее?

Viktor Borítás 28.03.2020 13:07

Фотогалерея 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.

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

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

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

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

Пример:

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

Метод pushState ():

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

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

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

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

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

мой код:

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

Это все :)

Я добился успеха с:

location.hash = "myValue";

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

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

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

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

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

Я представляю более простой ответ,

window.history.pushState(null, null, "/abc")

это добавит /abc после имени домена в URL-адресе браузера. Просто скопируйте этот код и вставьте его в консоль браузера, и вы увидите, как URL-адрес изменится на «https://stackoverflow.com/abc».

Другие вопросы по теме