web-dev-qa-db-fra.com

Quelles sont les différences entre history.pushState et location.hash?

J'essaie de mettre à jour l'URL en utilisant soit

  • window.location.hash ou
  • history.pushState.

Quelles sont les différences/avantages de chacun?

29
Krueger

location.hash a un meilleur support que le history.pushState méthode.
L'avantage de la méthode pushState est que vous pouvez lier un état à l'entrée d'historique.
Si vous n'avez pas besoin de cet objet d'état, je recommande d'utiliser le location.hash, pour une meilleure compatibilité avec les anciens navigateurs.

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"}
29
Rob W

Pushstate est l'avenir. C'est mieux parce que:

  1. Il a l'air plus propre.
  2. En revisitant un lien profond, vous pouvez réellement faire apparaître de vraies données côté serveur pour prendre en charge des choses comme le référencement et Facebook Open Graph (les deux envoient des araignées pour gratter le html de votre page).
  3. Les serveurs n'ont pas accès aux données des balises de hachage, vous ne les voyez donc pas dans les journaux de votre serveur, ce qui aide certaines analyses.
  4. Il aide à résoudre les problèmes de balises de hachage. Par exemple, j'ai eu une réécriture Nginx pour rediriger les utilisateurs visitant mon application vers la même URL https. Cela fonctionne dans tous les navigateurs, mais Safari qui vous redirigera vers le domaine sans le hachage (si ennuyeux)!
  5. Vous pouvez réellement utiliser une balise de hachage pour ce à quoi elle était destinée, un lien profond vers des sections de longues pages.
  6. Vous pouvez recourir à de vraies requêtes HTTP pour le navigateur qui ne prennent pas en charge l'état Push OR vous pouvez recourir à la balise de hachage. Les deux nécessitent une implémentation supplémentaire mais sont facilement réalisables avec un peu de travail.

Voir cette présentation du concepteur Github pour en savoir plus: http://warpspire.com/talks/responsive/

24
Mauvis Ledford

history.pushState est mieux que location.hash. mais c'est une fonctionnalité HTML5. donc toujours mieux d'avoir une méthode de secours comme ci-dessous.

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

Je suis d'accord avec les autres réponses, mais voici quelques arguments en faveur delocation.hash:

  • il fonctionne dans tous les navigateurs, y compris Internet ExploderTM
  • history.pushState est une norme en développement, et l'API pourrait changer à l'avenir
  • si les utilisateurs ouvrent un lien dans une nouvelle fenêtre/un nouvel onglet, une URL de hachage garantit qu'aucune demande de serveur n'est nécessaire pour charger la page (si les en-têtes de mise en cache corrects sont définis)
  • La configuration du serveur est facile, car tout ce que le serveur voit est l'URL sans partie de hachage

edit: j'en ai oublié un

  • avec des hashtags, vous pouvez utiliser de vrais liens (a href). Vous n'avez donc pas à configurer d'écouteurs de clics, ce qui améliore les performances et réduit la taille du code.
8
user123444555621

Les avantages/inconvénients de window.location.hash par rapport à HTML5 history.pushstate sont largement déterminés par la façon dont vous souhaitez que votre page se dégrade.

Ici, vous pourriez être intéressé par une dégradation gracieuse dans deux scénarios différents:

Le premier étant un client qui n'a pas activé javascript, ou un robot/robot automatisé visitant votre site. Ceci est particulièrement important du point de vue du référencement. Si votre page Web/application Web utilise des URL de hachage, le contenu disponible via ces liens n'est pas disponible pour ces utilisateurs finaux. C'est définitivement un problème si vous ne rendez des sections de contenu disponibles que via des hash-urls sans repli. Cependant, ce n'est certainement pas un problème si vous utilisez des liens de hachage pour modifier l'état de l'application qui ne conservent tout simplement pas de sens si la page se dégrade.

Par exemple, considérons un scénario dans lequel vous avez une page avec trois sections de texte disponibles dans trois onglets dans un widget de mise en page à onglets. Maintenant, il y a deux scénarios possibles: dans le premier, vous chargeriez tout le contenu pendant le chargement de la page - et le widget à onglets servira simplement à masquer d'autres sections et à afficher une section particulière. Par conséquent, si vous utilisez des URL de hachage dans les liens que vous utilisez pour créer les onglets des onglets, vous ne les utilisez que pour modifier l'état de l'application côté client. Lorsque javascript est désactivé/n'est pas disponible, simplement le javascript utilisé pour construire la disposition à onglets ne s'exécute pas, et tout le contenu est immédiatement disponible - une solution de rechange raisonnable et gracieuse. Les différents états d'application n'existent tout simplement pas dans ce cas et les URL de hachage se dégradent donc pour pointer simplement vers les ancres en html - l'objectif prévu. Au lieu de hash-urls si vous deviez utiliser pushstate html5 dans ce cas, ce serait une mauvaise idée. La raison pour laquelle un utilisateur peut ajouter le lien à un onglet particulier. Parce que votre serveur devrait prendre cette URL et présenter à l'utilisateur l'état côté client auquel il s'attend. Ce n'est pas bon pour une architecture de serveur léger où le côté client devrait prendre soin de sa propre gestion d'état. Vous pouvez bien sûr ignorer cet aspect côté serveur et laisser le client vérifier l'URL dès le début lors du chargement de la page, puis passer à l'état d'application approprié. Mais ce n'est toujours pas une bonne idée car votre système de routage côté serveur est concerné par la surcharge de fragments d'URL supplémentaires qu'il devrait ignorer, alors qu'il ne devrait pas être dérangé par ce fragment du tout d'un point de vue esthétique. Cela correspond exactement à l'exigence pour laquelle les URL de hachage ont été conçues et leur utilisation est fortement recommandée. Si, au contraire, dans les trois sections, le texte est chargé dynamiquement lorsqu'un clic sur un onglet particulier est cliqué, l'utilisation d'URL de hachage n'est pas une bonne idée. La raison étant que l'utilisateur n'aura tout simplement aucun moyen d'accéder au contenu lié si javascript n'est pas disponible. C'est particulièrement mauvais pour le référencement. Dans ce scénario, si vous gérez les URL (qui dans le scénario normal seraient "détournées" et "ajaxifiées") côté serveur pour rendre le contenu disponible en général, c'est excellent tant du point de vue de l'expérience de l'utilisateur final que du référencement.

Le deuxième scénario est un client qui possède un navigateur désuet qui ne prend pas en charge les pushstates html5. Bien que les points ci-dessus soient toujours valables, je dirais en outre que forcer les utilisateurs sans pushstate avec le même niveau de dégradation que le non-javascript n'est pas justifiable. De nombreux utilisateurs finaux n'auront tout simplement aucune idée de la raison pour laquelle ils reçoivent une version dégradée.

Je vous recommande de ne pas suivre la motivation dogmatique d'utiliser toujours les dernières technologies et de décider de la meilleure option pour votre scénario d'utilisation.

7
lorefnon

C'est une question assez ancienne (5 ans + au moment de cette réponse) mais beaucoup de commentaires sur les réponses existantes demandent une mise à jour basée sur l'état "actuel" des choses.

Voici l'affaire:

Le pushState de HTML5 est pris en charge sur tous les principaux navigateurs. Si vous prenez également en charge les anciens navigateurs, history.js fournit un excellent polyfill qui vous permet d'utiliser pushState en mode natif et de le faire facilement revenir aux URL héritées pour les anciens navigateurs. Maintenant que pushState est nativement pris en charge ne signifie pas, cependant, que c'est définitivement la voie à suivre.

Il y a un point très important qui n'a été soulevé dans aucune des réponses plus anciennes et c'est que les URL de hachage et les URL pushState sont non seulement différentes dans leur apparence, mais elles sont également différentes dans leur façon de fonctionner. Cette différence fondamentale entre les deux pourrait vous amener à choisir l'un plutôt que l'autre.

pushState est plus joli et plus propre et peut être utilisé pour simuler complètement la navigation sur votre site/dans votre application. Par exemple, GitHub l'utilise pour remplacer toute navigation de manière invisible. Lorsque vous cliquez sur un lien sur leur site, javascript est utilisé pour intercepter ce clic et le transformer en une demande AJAX qui met à jour le contenu de la page sans charger une nouvelle page, tandis que l'URL dans le la barre d'emplacement change pour correspondre au contenu qui a été récupéré. C'est pour cela que pushState devait être utilisé.

Dans le cas de GitHub, http: // mysite/page1 et http: // mysite/page2 sont tous deux des URL valides. Ce sont de "vrais" liens avec un "vrai" contenu, et la visite initiale de l'une ou l'autre page passe par l'approche MVC traditionnelle. GitHub utilise pushState pour la navigation dans les navigateurs modernes, mais ne l'exige pas - c'est-à-dire que pushState est utilisé comme un "ajout de fonctionnalité" pour (à leur avis) conduire à une meilleure expérience utilisateur en matière de navigation. Lorsque vous copiez le lien dans la barre d'adresse du navigateur, vous copiez un lien qui a été formé via javascript & pushState, mais un lien qui est néanmoins réel et valide.

Cependant, si vous commencez à gratter et à créer une application d'une seule page et que vous n'utilisez pas de framework MVC, il est probable que vous n'ayez en fait qu'une seule page, surtout si vous n'utilisez pas de backend dynamique (c'est-à-dire que le contenu est entièrement récupéré via javascript , jamais généré par un serveur). Dans ce cas, si vous utilisez pushState sur des URL de hachage, vous devrez gérer le cas où l'URL dans le navigateur n'est pas la véritable URL. Je vais illustrer.

L'utilisateur charge votre application d'une seule page: http: // mysite/mainpage

À ce stade, la barre de navigation contient le véritable lien vers votre application et amènera l'utilisateur à la même vue qu'il voit actuellement: la page principale. Maintenant, ils cliquent sur un lien qui les mènera à une "page" affichant les détails d'une activité. À ce stade, vous souhaitez mettre à jour la barre d'emplacement pour indiquer le changement d'état. Soit vous utilisez une URL de hachage et votre barre d'emplacement ressemble à http: // mysite/mainpage # charts/1 soit vous utilisez pushState et la trompez pour qu'elle devienne http: // mysite/mainpage/graphiques/1

Si vous avez utilisé pushState, ce n'est pas un vrai lien. La navigation via les boutons Précédent/Suivant du navigateur fonctionnera très bien et l'utilisateur ira de la page principale à la page de détail dans la barre d'emplacement et dans l'application (en supposant que vous gérez correctement le changement d'état), mais si l'utilisateur marque ce lien dans les favoris ou copie et colle le lien pour le partager, un vaudou côté serveur supplémentaire sera requis.

Vous devrez rediriger les demandes vers/mainpage/charts/1 vers/mainpage, puis utiliser JS pour résoudre l'URL réelle et effectuer l'opération de changement d'état prévue. Une redirection du serveur est absolument nécessaire. Vous ne pouvez pas héberger cette page sur AWS ou sur votre disque local sans un serveur http scriptable.

Maintenant, si vous avez utilisé des URL de hachage, votre URL avec laquelle l'utilisateur aurait vu et interagi aurait été http: // mysite/mainpage #/charts/1 et qui est valide, vraie URL. Les navigateurs comprennent qu'il n'y a qu'une seule page, et que l'utilisateur copie et colle le lien ou les signets, il vous suffit de gérer l'état de hachage en javascript et de ne pas avoir besoin de magie côté serveur pour que les choses fonctionnent.

Ce que personne ne semble mentionner, c'est que les liens pushState et hash ne s'excluent pas mutuellement . pushState est juste une API pour manipuler l'emplacement du navigateur visible par l'utilisateur et implémenter une navigation avant/arrière fiable dans les navigateurs modernes. Il ne dit rien à quoi devrait ressembler votre schéma d'URL.

En 2017, Google et à peu près tous les autres robots compatibles JS comprennent les URL de hachage et les parcourent très bien. Google veut que vous utilisiez le #! abomination à des fins de maximisation du référencement, mais même si vous ne le faites pas, votre site sera très bien navigable.

La bonne réponse consiste à utiliser ce qui correspond le mieux à vos besoins. Si vous avez de vraies URL et que vous souhaitez simuler la navigation entre elles, utilisez pushState et continuez (éventuellement avec un polyfill pour les navigateurs plus anciens). Mais si vous avez une application d'une seule page, ne faites pas semblant de ne pas le faire (sauf si vous avez une très bonne raison). Utilisez des URL de hachage pour vous simplifier la vie et ne pas introduire de problèmes inutiles puis utilisez pushState pour manipuler ces URL de hachage pour profiter d'un meilleur support arrière/avant.

6
Mahmoud Al-Qudsi

Actuellement, pushState est pris en charge par tous les navigateurs modernes. Par conséquent, pushState est meilleur que location.hash, mais c'est une fonctionnalité HTML5.

Alors, location.hash n'est pas mort, en fait il sera là pour très longtemps.

Une bonne façon de l'utiliser est avec une bibliothèque qui prend en charge pushState, mais se dégrade également avec élégance en utilisant location.hash.
Exemple - https://github.com/browserstate/history.js

De plus location.hash sera toujours utile pour passer aux ancres nommées. pushState sera d'une aide précieuse dans la création d'applications Web. J'ai hâte de l'utiliser.

2
Shivam Mathur

Personnellement, je préfère pushState car cela rend les URL plus belles et je pense que c'est important pour l'expérience utilisateur.

Vous pouvez utiliser history.pushState avec un hachage de secours en utilisant le history.js polyfill si vous voulez utiliser pushState, mais ne voulez pas avoir de problèmes avec le support du navigateur plus ancien.

1
kbjr