Подтвердить что ты не робот

Каковы различия между history.pushState и location.hash?

Я пытаюсь обновить URL с помощью

  • window.location.hash или
  • history.pushState.

Каковы различия/преимущества каждого?

4b9b3361

Ответ 1

location.hash имеет лучшую поддержку, чем history.pushState.
Преимущество метода pushState заключается в том, что вы можете привязать состояние к записи истории.
Если вам не нужен этот объект состояния, я рекомендую использовать свойство location.hash для лучшей совместимости со старыми браузерами.

location.hash = 'new-hash';
console.log(history.state); // null or undefined

history.pushState({extraData: "some state info"}, '', 'new-hash'); //<---
console.log(history.state); // [object Object] = {"extraData": "some state info"}

Ответ 2

Pushstate - это будущее. Это лучше, потому что:

  • Он выглядит чище.
  • При повторном просмотре глубокой ссылки вы можете на самом деле наглядно представить реальные серверные данные для поддержки таких вещей, как SEO и Facebook Open Graph (оба посылают пауки, чтобы очистить html вашей страницы).
  • Серверы не имеют доступа к данным хэш-тегов, поэтому вы не видите их в своих журналах сервера, поэтому это помогает некоторым аналитикам.
  • Он помогает исправлять проблемы с хэш-тегами. Например, у меня была перезапись Nginx, чтобы перенаправить пользователей, посещающих мое приложение, на тот же https-url. Он работает во всех браузерах, но Safari, который перенаправит вас только на домен без хеша (так раздражает)!
  • Фактически вы можете использовать хэш-тег для того, что предназначалось для глубокой привязки к разделам длинных страниц.
  • Вы можете отказаться от использования реальных HTTP-запросов на бэкэнд для браузера, которые не поддерживают push state, или вы можете отказаться от использования хэш-тега. Оба требуют дополнительной реализации, но легко выполняются с небольшой работой.

См. этот разговор от дизайнера Github для более подробной информации: http://warpspire.com/talks/responsive/

Ответ 3

history.pushState лучше, чем location.hash. но это функция HTML5. поэтому всегда лучше иметь метод возврата, как показано ниже.

if (typeof(window.history.pushState) == 'function') {
    window.history.pushState(null, path, path);
} else {
    window.location.hash = '#!' + path;
}

Ответ 4

Я согласен с другими ответами, но вот несколько аргументов в пользу location.hash:

  • он работает в каждом браузере, включая Internet Exploder TM
  • history.pushState является стандартом разработки, и API может измениться в будущем.
  • Если пользователи открывают ссылку в новом окне/вкладке, хеш-URL-адрес гарантирует, что для загрузки страницы не требуется запрос сервера (если установлены правильные заголовки кеширования)
  • Конфигурация сервера проста, поскольку весь сервер когда-либо видит URL без хэш-части

edit: Я забыл один

  • с hashtags, вы можете использовать реальные ссылки (a href). Таким образом, вам не нужно настраивать прослушиватели кликов, что повышает производительность и уменьшает размер кода.

Ответ 5

Преимущества/недостатки window.location.hash vs HTML5 history.pushstate во многом определяются тем, как именно вы хотите, чтобы ваша страница ухудшалась.

Здесь вы можете быть заинтересованы в изящном ухудшении в двух разных сценариях:

Первый из них - клиент, который не имеет включенного javascript, или автоматический робот/искатель, посещающий ваш сайт. Это особенно важно с точки зрения SEO. Если ваша веб-страница/веб-приложение использует хеш-URL, то контент, доступный через эти ссылки, не доступен этим конечным пользователям. Это определенно проблема, если вы делаете разделы контента доступными только через хэш-URL без резервов. Однако это определенно не проблема, если вы используете ссылки hash-tag для изменения состояния приложения, которое просто не сохраняет значение, если страница ухудшается.

В качестве примера рассмотрим сценарий, в котором у вас есть страница с тремя разделами текста, доступная на трех вкладках в виджетах с вкладками. Теперь возможны два сценария: во-первых, вы загружаете весь контент во время загрузки страницы, а виджет с вкладками будет просто скрывать другие разделы и показывать определенный раздел. Поэтому, если вы используете хеш-ссылки в ссылках, которые вы используете для создания вкладок, вы используете их только для изменения состояния приложения на стороне клиента. Когда javascript отключен/недоступен, просто javascript, используемый для построения макета с вкладками, не запускается, и весь контент сразу доступен - разумный изящный откат. Различные состояния приложения просто не существуют в этом случае, и поэтому хэш-URL-адреса ухудшаются до того, чтобы указывать на якоря в html - цель. Вместо хэш-ссылок, если бы вы использовали html5 pushstate в этом случае, это была бы плохая идея. Причина, по которой пользователь может добавить ссылку на конкретную вкладку. Поскольку ваш сервер должен будет взять этот URL-адрес и представить пользователю состояние клиентской стороны, которое он ожидает. Это плохо для архитектуры тонкого сервера, где клиентская сторона должна заботиться о своем собственном управлении государством. Вы можете игнорировать этот аспект на стороне сервера и позволить клиенту проверить URL-адрес в начале загрузки страницы, а затем переключиться в соответствующее состояние приложения. Но все же это не очень хорошая идея, потому что ваша система маршрутизации на стороне сервера связана с накладными расходами дополнительных фрагментов URL-адресов, которые она должна игнорировать, где это не должно беспокоить этот фрагмент вообще с эстетической точки зрения. Это точно соответствует требованию, для которого были разработаны хэш-URL, и настоятельно рекомендуется использовать их. Если вместо этого в трех разделах текст загружается динамически, когда нажимается конкретный большой палец вкладки, то использование хеш-ссылок не является хорошей идеей. Причина, по которой пользователь будет просто не иметь доступа к связанному контенту, если javascript недоступен. Это особенно плохо для SEO. В этом случае, если вы обрабатываете URL-адреса (которые в обычном сценарии будут "захвачены" и "ааксифицированы" ) на стороне сервера, чтобы сделать контент доступным в целом, он отлично подходит как с точки зрения опыта конечных пользователей, так и с помощью SEO.

Второй сценарий - это клиент, у которого есть устаревший браузер, который не поддерживает pushstates html5. В то время как вышеупомянутые пункты все еще сохраняются, кроме того, я бы также утверждал, что принуждение пользователей без какой-либо pushstate с тем же уровнем деградации, что и не-javascript не является оправданным. Многие конечные пользователи просто не знают, почему они получают ухудшенную версию.

Я бы порекомендовал вам не отмечать наряду с догматической мотивацией использовать новейшие технологии и решать самый лучший вариант для вашего сценария использования.

Ответ 6

Это довольно старый вопрос (5 years+ во время этого ответа), но многие комментарии к существующим ответам требуют обновления, основанного на "текущем" состоянии вещей.

Здесь сделка:

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

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

pushState красивее и чище и может быть использован для полной имитации навигации по вашему сайту/в вашем приложении. Например, GitHub использует его, чтобы незаметно заменить всю навигацию. Когда вы нажимаете любую ссылку на их сайте, javascript используется для перехвата этого клика и превращения его в запрос AJAX, который обновляет содержимое страницы без загрузки новой страницы, в то время как URL-адрес в строке адреса изменяется в соответствии с содержимым, которое было неправдоподобным. Вот для чего нужно было использовать pushState.

В случае с GitHub http://mysite/page1 и http://mysite/page2 являются действительными URL-адресами. Это "реальные" ссылки с "реальным" контентом, и первоначально посещение любой страницы проходит через традиционный подход MVC. GitHub использует pushState для навигации в современных браузерах, но не требует этого - то есть pushState используется как "добавление функции", чтобы (по их мнению) улучшить восприятие пользователем, когда дело доходит до навигации. Когда вы копируете ссылку в адресной строке браузера, вы копируете ссылку, созданную с помощью javascript & pushState, но ссылка, тем не менее, реальная и действительная.

Однако, если вы начинаете с нуля и создаете одностраничное приложение и не используете инфраструктуру MVC, есть вероятность, что у вас на самом деле есть только одна страница, особенно если вы не используете динамический бэкэнд (т.е. все содержимое извлекается с помощью javascript, никогда не генерируется сервером). В этом случае, если вы используете pushState поверх хеш-URL, вам нужно будет обработать случай, когда URL в браузере не является реальным URL. Я проиллюстрирую.

Пользователь загружает ваше одностраничное приложение: http://mysite/mainpage

На этом этапе панель браузера содержит реальную ссылку на ваше приложение и приведет пользователя к тому же представлению, которое они в данный момент видят: главной странице. Теперь они нажимают на ссылку, которая приведет их на "страницу", показывающую детали некоторых действий. На данный момент вы хотите обновить адресную строку, чтобы указать изменение в состоянии. Вы либо используете хеш-URL, и ваша строка местоположения выглядит как http://mysite/mainpage#charts/1, либо вы используете pushState и обманывает его, чтобы он стал http://mysite/mainpage/charts/1

Если вы использовали pushState, это не настоящая ссылка. Навигация по браузеру с помощью кнопок "назад" и "вперед" будет работать отлично, и пользователь перейдет с главной страницы на страницу сведений как в строке местоположения, так и в приложении (при условии, что вы правильно изменили состояние), но если пользователь добавит эту ссылку в закладки или скопируйте и вставьте ссылку, чтобы поделиться ею, потребуется дополнительная серверная voodoo.

Вам нужно будет перенаправить запросы на /mainpage/charts/1 на /mainpage, а затем использовать JS для разрешения фактического URL-адреса и выполнения предполагаемой операции изменения состояния. Перенаправление сервера абсолютно необходимо. Эту страницу нельзя разместить на AWS или на локальном диске без http-сервера со сценариями.

Теперь, если бы вы использовали хеш-URL-адреса, ваш URL-адрес, с которым бы пользователь видел и взаимодействовал, был бы http://mysite/mainpage#/charts/1, и это действительный, настоящий URL-адрес. Браузеры понимают, что существует только одна страница, и независимо от того, копирует ли пользователь и вставляет ли ссылку или добавляет ее в закладки, вам просто нужно обработать хеш-состояние в javascript и не нужно никакого волшебства на стороне сервера, чтобы все заработало.

Кажется, никто не упоминает, что pushState и хеш-ссылки не являются взаимоисключающими. pushState - это просто API-интерфейс для манипулирования местоположением браузера, видимым для пользователя, и реализации надежной навигации назад/вперед в современных браузерах. В нем ничего не говорится о том, как должна выглядеть ваша схема URL.

В 2017 году Google и почти каждый другой бот, поддерживающий JS, понимают URL-адреса хэшей и проходят их очень хорошо. Google хочет, чтобы вы использовали #! мерзость для SEO в целях максимизации, но даже если вы этого не сделаете, ваш сайт будет хорошо ориентироваться.

Правильный ответ - использовать то, что соответствует вашим потребностям. Если у вас есть реальные URL-адреса и вы хотите имитировать навигацию между ними, используйте pushState и продолжайте (опционально с полифилом для старых браузеров). Но если у вас есть одностраничное приложение, не делайте вид, что нет (если у вас нет веских причин). Используйте URL-адреса хеширования, чтобы упростить вашу жизнь, и не создавайте ненужных проблем, а затем используйте pushState, чтобы манипулировать этими URL-адресами хэш-функции, чтобы воспользоваться преимуществами лучшей поддержки "назад/вперед".

Ответ 7

В настоящее время pushState поддерживается всеми современными браузерами. Поэтому pushState лучше, чем location.hash, но это функция HTML5.

Итак, location.hash не мертв, на самом деле он будет длиться долгое время.

Хороший способ использовать это с lib, который поддерживает pushState, но также изящно ухудшает использование location.hash.
Пример - https://github.com/browserstate/history.js

Более того, location.hash по-прежнему будет полезен для перехода к названным якорям. pushState будет огромной помощью в создании веб-приложений. Я с нетерпением жду его использования.

Ответ 8

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

Вы можете использовать history.pushState с хеш-резервом, используя history.js polyfill, если вы хотите использовать pushState, t хотят иметь проблемы со старой поддержкой браузера.