Я пытаюсь обновить URL с помощью
window.location.hash
илиhistory.pushState
.
Каковы различия/преимущества каждого?
Я пытаюсь обновить URL с помощью
window.location.hash
илиhistory.pushState
.Каковы различия/преимущества каждого?
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"}
Pushstate - это будущее. Это лучше, потому что:
См. этот разговор от дизайнера Github для более подробной информации: http://warpspire.com/talks/responsive/
history.pushState
лучше, чем location.hash
. но это функция HTML5. поэтому всегда лучше иметь метод возврата, как показано ниже.
if (typeof(window.history.pushState) == 'function') {
window.history.pushState(null, path, path);
} else {
window.location.hash = '#!' + path;
}
Я согласен с другими ответами, но вот несколько аргументов в пользу location.hash
:
edit: Я забыл один
a href
). Таким образом, вам не нужно настраивать прослушиватели кликов, что повышает производительность и уменьшает размер кода.Преимущества/недостатки 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 не является оправданным. Многие конечные пользователи просто не знают, почему они получают ухудшенную версию.
Я бы порекомендовал вам не отмечать наряду с догматической мотивацией использовать новейшие технологии и решать самый лучший вариант для вашего сценария использования.
Это довольно старый вопрос (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-адресами хэш-функции, чтобы воспользоваться преимуществами лучшей поддержки "назад/вперед".
В настоящее время pushState
поддерживается всеми современными браузерами. Поэтому pushState
лучше, чем location.hash
, но это функция HTML5.
Итак, location.hash
не мертв, на самом деле он будет длиться долгое время.
Хороший способ использовать это с lib, который поддерживает pushState
, но также изящно ухудшает использование location.hash
.
Пример - https://github.com/browserstate/history.js
Более того, location.hash
по-прежнему будет полезен для перехода к названным якорям.
pushState
будет огромной помощью в создании веб-приложений. Я с нетерпением жду его использования.
Я лично предпочитаю pushState, потому что он делает более привлекательные URL-адреса, и я думаю, что это важно для пользователей.
Вы можете использовать history.pushState
с хеш-резервом, используя history.js polyfill, если вы хотите использовать pushState, t хотят иметь проблемы со старой поддержкой браузера.