Comment vérifier si l'utilisateur peut revenir ou non dans l'historique du navigateur


Réponses:


119

Réponse courte: vous ne pouvez pas.

Techniquement, il existe un moyen précis, qui serait de vérifier la propriété:

history.previous

Cependant, cela ne fonctionnera pas. Le problème avec cela est que dans la plupart des navigateurs, cela est considéré comme une violation de sécurité et renvoie généralement simplement undefined .

history.length

C'est une propriété que d'autres ont suggérée ...
Cependant , la longueur ne fonctionne pas complètement car elle n'indique pas vous vous trouvez dans l'histoire. De plus, il ne commence pas toujours par le même numéro. Un navigateur qui n'est pas configuré pour avoir une page de destination, par exemple, commence à 0 tandis qu'un autre navigateur qui utilise une page de destination démarre à 1.

texte alternatif

La plupart du temps, un lien est ajouté qui appelle:

history.back();

ou

 history.go(-1);

et on s'attend simplement à ce que si vous ne pouvez pas revenir en arrière, cliquer sur le lien ne fait rien.


Ce sont de bonnes informations, mais cela ne résout pas le problème. Ce serait d'élaborer un code qui fonctionne réellement sur n'importe quel navigateur. Peut-être un code qui vérifie d'abord le navigateur que vous utilisez.
Santiago Bendavid

5
Ce que je dis, c'est qu'il n'y a pas de réponse définitive. Vous dites les avantages et les inconvénients de chaque approche, mais pas comment obtenir un script qui vérifie quel navigateur vous utilisez et exécutez conditionnellement l'un ou l'autre des morceaux de code.
Santiago Bendavid

Puis-je savoir ce que vous entendez par `` Le problème avec ceci est que dans la plupart des navigateurs, cela est considéré comme une violation de la sécurité '' Un autre utilisateur dans un autre fil a également souligné que pouvoir obtenir l'historique du navigateur du client enfreint la sécurité, mais n'explique pas pourquoi donc. Quelqu'un peut-il donner un exemple des menaces à la sécurité?
Kevin Chandra

Un site Web ne devrait pas être en mesure de connaître l'historique d'un utilisateur qui pourrait inclure des informations personnelles indirectes. Un site peut utiliser des suivis / cookies pour savoir ce que l'utilisateur fait sur le site lui-même, mais il ne devrait pas, par exemple, être autorisé à déterminer quelle banque j'utilise, à quelle école mes enfants vont, etc. les navigateurs ne permettent pas l'accès à cette propriété
McAden

85

Il existe une autre façon de vérifier - vérifiez le référent. La première page aura généralement un référent vide ...

if (document.referrer == "") {
    window.close()
} else {
    history.back()
}

3
Le référent peut être masqué pour des raisons de confidentialité.
Kornel

11
Le référent est toujours vide lorsqu'une page n'a pas été chargée par un lien mais en entrant l'URL dans la barre d'adresse, ou en chargeant un signet. De telles pages peuvent cependant avoir un historique, lorsque l'onglet / la fenêtre du navigateur avait chargé une autre page auparavant!
ygoe le

1
Mais est une solution applicable pour la navigation sur le site Web de plusieurs pages
Dan

36
Ne fonctionne pas si une fenêtre a été ouverte avec target = "_ blank" pour forcer une nouvelle fenêtre. Le bouton de retour sur le navigateur ne fonctionnera pas, mais il y aura un document.referrer
Mike_K

3
Cela ne fonctionnera pas si vous venez d'une page sécurisée (HTTPS) vers une page non sécurisée (HTTP), car cela supprimera le référent.
Kevin Borders

55

Mon code laisse le navigateur revenir d'une page en arrière, et si cela échoue, il charge une URL de secours. Il détecte également les changements de hashtags.

Lorsque le bouton de retour n'était pas disponible, l'URL de secours sera chargée après 500 ms, de sorte que le navigateur a suffisamment de temps pour charger la page précédente. Le chargement de l'URL de secours juste après window.history.go(-1);obligerait le navigateur à utiliser l'URL de secours, car le script js ne s'est pas encore arrêté.

function historyBackWFallback(fallbackUrl) {
    fallbackUrl = fallbackUrl || '/';
    var prevPage = window.location.href;

    window.history.go(-1);

    setTimeout(function(){ 
        if (window.location.href == prevPage) {
            window.location.href = fallbackUrl; 
        }
    }, 500);
}

7
Je pense que cela cloue vraiment le cœur de la question, la raison pour laquelle une personne se soucie et ce qui peut réellement être fait à ce sujet de manière fiable et cohérente.
Chris Marisic

1
Cela a fonctionné jusqu'à ce que je prenne l'URL où se trouve le bouton de retour et que je la colle dans un nouvel onglet dans Chrome. En cliquant sur le bouton de retour, vous avez été envoyé vers un onglet vide. :(
karlingen

3
C'est le comportement par défaut de Chrome. Vous avez "visité" la page chrome://newtabet ainsi vous pouvez revenir dans l'histoire.
redelschaap

Attention, car avec une connexion réseau lente, vous allez frapper assez régulièrement l'URL de secours.
cameck

14

Voici comment je l'ai fait.

J'ai utilisé l' événement 'beforeunload' pour définir un booléen. Ensuite, j'ai défini un délai pour regarder si le 'beforeunload' se déclenche.

var $window = $(window),
    $trigger = $('.select_your_link'),
    fallback = 'your_fallback_url';
    hasHistory = false;

$window.on('beforeunload', function(){
    hasHistory = true;
});

$trigger.on('click', function(){

    window.history.go(-1);

    setTimeout(function(){
        if (!hasHistory){
            window.location.href = fallback;
        }
    }, 200);

    return false;
});

Semble fonctionner dans les principaux navigateurs (testé FF, Chrome, IE11 jusqu'à présent).


1
C'est de loin la meilleure réponse à la question. Vous pouvez facilement remplacer window.location.href = fallbackpar window.close()et cela fonctionne aussi.
Vitani

13

cela semble faire l'affaire:

function goBackOrClose() {  

    window.history.back();
    window.close(); 

    //or if you are not interested in closing the window, do something else here
    //e.g. 
    theBrowserCantGoBack();

}

Appelez history.back () puis window.close (). Si le navigateur est capable de revenir dans l'historique, il ne pourra pas accéder à l'instruction suivante. S'il ne peut pas revenir en arrière, il fermera la fenêtre.

Cependant, veuillez noter que si la page a été atteinte en tapant une URL, Firefox n'autorisera pas le script à fermer la fenêtre.


3
J'ai trouvé que cela ne fonctionne pas à moins que j'utilise un setTimeout avec un délai de quelques centaines de millisecondes environ avant d'essayer d'exécuter l'instruction suivante, sinon cela fonctionnera de toute façon après l'exécution de history.back ()
Ken Fehling

Je n'ai pas vécu cela personnellement, de quel navigateur s'agissait-il?
xtrahelp.com

J'avais bien travaillé avec la fonction setTimeout dans la réponse ci-dessous. ex: setTimeout (function () {window.close ()}, 400);
gilchris

2
window.close()est considéré comme un risque de sécurité par de nombreux navigateurs modernes. Certains ne vous laisseront pas faire.
Rudi Kershaw

vous pouvez tout faire après window.history.back (); window.close (); est juste un exemple
hariszaman

13

Il y a un extrait que j'utilise dans mes projets:

function back(url) {
    if (history.length > 2) {
        // if history is not empty, go back:
        window.History.back();
    } else if (url) {
        // go to specified fallback url:
        window.History.replaceState(null, null, url);
    } else {
        // go home:
        window.History.replaceState(null, null, '/');
    }
}

Pour info: j'utilise History.js pour gérer l'historique du navigateur.


Pourquoi comparer history.length au numéro 2?

Parce que la page d'accueil de Chrome est comptée comme le premier élément de l'historique du navigateur.


Il y a peu de possibilités history.lengthet de comportement de l'utilisateur:

  • L'utilisateur ouvre un nouvel onglet vide dans le navigateur, puis exécute une page. history.length = 2et nous voulons désactiver back()dans ce cas, car l'utilisateur ira à l'onglet vide.
  • L'utilisateur ouvre la page dans un nouvel onglet en cliquant sur un lien quelque part avant. history.length = 1et encore une fois, nous voulons désactiver la back()méthode.
  • Et enfin, l'utilisateur atterrit sur la page actuelle après avoir rechargé quelques pages . history.length > 2et maintenant back()peut être activé.

Remarque: j'omets le cas où l'utilisateur atterrit sur la page actuelle après avoir cliqué sur le lien du site Web externe sans target="_blank".

Note 2: document.referrer est vide lorsque vous ouvrez le site Web en tapant son adresse et également lorsque le site Web utilise ajax pour charger des sous-pages, j'ai donc arrêté de vérifier cette valeur dans le premier cas.


Cette approche a très bien fonctionné pour moi. En fait, je stocke des liens de secours statiques pour mes pages que j'utilise sur la solution de secours.
Greg Blass

Mais, si vous revenez en arrière, la longueur de l'histoire ne changera pas .. Donc, cela ne fonctionne pas correctement
Ciprian Mocanu

Vous avez raison, malheureusement. J'utilise cet extrait avec la structure "one-step-back" uniquement…
gregmatys

10

Soyez prudent window.history.lengthcar il inclut également des entrées pourwindow.history.forward()

Ainsi, vous pouvez avoir peut-être window.history.lengthplus de 1 entrées, mais aucune entrée d'historique. Cela signifie que rien ne se passe si vous tirezwindow.history.back()


9

Vous ne pouvez pas vérifier directement si le bouton de retour est utilisable. Vous pouvez regarder history.length>0, mais cela sera vrai s'il y a également des pages avant la page actuelle. Vous ne pouvez être sûr que le bouton de retour est inutilisable lorsque history.length===0.

Si cela ne suffit pas, il vous suffit d'appeler history.back()et, si votre page est toujours chargée par la suite, le bouton retour n'est pas disponible! Bien sûr, cela signifie que si le bouton de retour est disponible, vous venez de quitter la page. Vous n'êtes pas autorisé à annuler la navigation dans onunload, donc tout ce que vous pouvez faire pour empêcher le retour de se produire est de renvoyer quelque chose onbeforeunload, ce qui entraînera l'apparition d'une grande invite ennuyeuse. Ça ne vaut pas le coup.

En fait, c'est normalement une très mauvaise idée de faire quoi que ce soit avec l'histoire. La navigation dans l'historique concerne le chrome du navigateur, pas les pages Web. L'ajout de liens «retour» provoque généralement plus de confusion pour les utilisateurs que cela ne vaut la peine.


2
en ce qui concerne la longueur - même pas dans tous les navigateurs. Certains navigateurs comptent la page actuelle comme un élément de l'historique et commencent à 1. Vous devrez inclure la détection du navigateur.
McAden

En fait, j'ai pensé que c'était toujours le cas 1! Le 0était un brainfart, je pensais que les navigateurs seraient toujours répondre avec 1ou plus. Il s'avère qu'Opera et IE pensent le contraire - bonne prise.
bobince

1
"La navigation dans l'historique est pour le chrome du navigateur, pas pour les pages Web" - D'accord
Brian

5

history.lengthest inutile car il ne montre pas si l'utilisateur peut revenir dans l'histoire. De plus, différents navigateurs utilisent les valeurs initiales 0 ou 1 - cela dépend du navigateur.

La solution de travail consiste à utiliser l' $(window).on('beforeunload'événement, mais je ne suis pas sûr que cela fonctionnera si la page est chargée via ajax et utilise pushState pour modifier l'historique de la fenêtre.

J'ai donc utilisé la solution suivante:

var currentUrl = window.location.href;
window.history.back();
setTimeout(function(){
    // if location was not changed in 100 ms, then there is no history back
    if(currentUrl === window.location.href){
        // redirect to site root
        window.location.href = '/';
    }
}, 100);

Fonctionne pour moi comme ceci: function goBackOrTo (targetUrl) {var currentUrl = window.location.href; window.history.go (-1); setTimeout (function () {// si l'emplacement n'a pas été changé dans 800 ms, alors il n'y a pas d'historique en arrière if (currentUrl === window.location.href) {// rediriger vers la racine du site window.location.href = targetUrl; }}, 800); }
alfonx

2

J'ai proposé l'approche suivante. Il utilise l'événement onbeforeunload pour détecter si le navigateur commence à quitter la page ou non. Si ce n'est pas le cas dans un certain laps de temps, il sera simplement redirigé vers la solution de secours.

var goBack = function goBack(fallback){
    var useFallback = true;

    window.addEventListener("beforeunload", function(){
      useFallback = false;
    });

    window.history.back();

    setTimeout(function(){
        if (useFallback){ window.location.href = fallback; }
    }, 100); 
}

Vous pouvez appeler cette fonction en utilisant goBack("fallback.example.org").


1
C'est ce que j'aime le plus, je viens de passer windows.onbeforeunloadà l'écouteur d'événements window.addEventListener("beforeunload", function (event) { useFallback = false; });pour qu'il n'écrase pas window.onbeforeunload.
MiChAeLoKGB

2

Construire sur la réponse ici et ici . Je pense que la réponse la plus concluante est simplement de vérifier s'il s'agit d'une nouvelle page dans un nouvel onglet.

Si l'historique de la page est plus d'un, alors nous pouvons revenir à la page précédente à la page actuelle. Sinon, l'onglet est un onglet nouvellement ouvert et nous devons créer un nouvel onglet.

À la différence des réponses liées, nous ne vérifions pas un referrercar un nouvel onglet aura toujours un référent.

if(1 < history.length) {
    history.back();
}
else {
    window.close();
}

1
Je vous remercie. Vous avez sauvé ma journée :).
Bijay Yadav

1

Il existe une autre solution presque parfaite, tirée d' une autre réponse SO :

if( (1 < history.length) && document.referrer ) {
    history.back();
}
else {
    // If you can't go back in history, you could perhaps close the window ?
    window.close();
}

Quelqu'un a signalé que cela ne fonctionne pas lors de l'utilisation, target="_blank"mais cela semble fonctionner pour moi sur Chrome.


0

le navigateur a le bouton précédent et suivant. Je trouve une solution sur cette question. mais cela affectera l'action de transfert du navigateur et causera des bogues avec certains navigateurs.

Cela fonctionne comme ça: Si le navigateur ouvre une nouvelle URL, qui ne s'est jamais ouverte, la longueur de history.length augmentera.

afin que vous puissiez changer le hachage comme

  location.href = '#__transfer__' + new Date().getTime() 

pour obtenir une URL jamais affichée, alors history.length aura la vraie longueur.

  var realHistoryLength = history.length - 1

mais, cela ne fonctionne pas toujours bien, et je ne sais pas pourquoi, en particulier lorsque l'URL saute rapidement.


0

J'essayais de trouver une solution et c'est la meilleure que je puisse obtenir (mais fonctionne très bien et c'est la solution la plus simple que j'ai trouvée même ici).

Dans mon cas, je voulais revenir sur l'historique avec un bouton de retour, mais si la première page ouverte par l'utilisateur était une sous-page de mon application, elle reviendrait à la page principale.

La solution était, dès que l'application est chargée, je viens de faire un remplacement sur l'état de l'historique:

history.replaceState( {root: true}, '', window.location.pathname + window.location.hash)

De cette façon, j'ai juste besoin de vérifier history.state.rootavant de revenir en arrière. Si c'est vrai, je fais un remplacement d'historique à la place:

if(history.state && history.state.root)
    history.replaceState( {root: true}, '', '/')
else
    history.back() 

Je ne pense pas qu'il y ait d'autre bon cas d'utilisation. Ce n'est peut-être pas une bonne idée si vous souhaitez consulter l'historique en dehors de votre application.
Maxwell sc

-1
var fallbackUrl = "home.php";
if(history.back() === undefined)
    window.location.href = fallbackUrl;

ça a l'air super facile?! est-il testé sur les différents navigateurs?
benzkji

dans Chrome history.back()est undefineduniquement sur la page à onglet vide
gregmatys

-2

Solution

'use strict';
function previousPage() {
  if (window.location.pathname.split('/').filter(({ length }) => length > 0).length > 0) {
    window.history.back();
  }
}

Explication

window.location.pathnamevous donnera l'URI actuel. Par exemple https://domain/question/1234/i-have-a-problemdonnera /question/1234/i-have-a-problem. Voir la documentation sur window.location pour plus d'informations.

Ensuite, l'appel à split()nous donnera tous les fragments de cet URI. donc si nous prenons notre URI précédent, nous aurons quelque chose comme ["", "question", "1234", "i-have-a-problem"]. Voir la documentation sur String.prototype.split () pour plus d'informations.

L'appel à filter()est là pour filtrer la chaîne vide générée par la barre oblique inverse. Il renverra essentiellement uniquement l'URI du fragment qui a une longueur supérieure à 1 (chaîne non vide). Donc, nous aurions quelque chose comme ["question", "1234", "i-have-a-question"]. Cela aurait pu être écrit comme ceci:

'use strict';
window.location.pathname.split('/').filter(function(fragment) {
  return fragment.length > 0;
});

Voir la documentation sur Array.prototype.filter () et l' affectation Destructuring pour plus d'informations.

Maintenant, si l'utilisateur essaie de revenir en arrière tout en étant https://domain/allumé, nous ne déclencherons pas l'instruction if, et nous ne déclencherons donc pas la window.history.back()méthode pour que l'utilisateur reste sur notre site Web. Cette URL sera équivalente à []laquelle a une longueur de 0et 0 > 0est fausse. Par conséquent, échouant silencieusement. Bien sûr, vous pouvez enregistrer quelque chose ou avoir une autre action si vous le souhaitez.

'use strict';
function previousPage() {
  if (window.location.pathname.split('/').filter(({ length }) => length > 0).length > 0) {
    window.history.back();
  } else {
    alert('You cannot go back any further...');
  }
}

Limites

Bien sûr, cette solution ne fonctionnera pas si le navigateur ne prend pas en charge l' API History . Consultez la documentation pour en savoir plus avant d'utiliser cette solution.


-5

Je ne sais pas si cela fonctionne et ce n'est pas du tout testé, mais essayez ceci:

<script type="text/javascript">

    function goBack() {
        history.back();
    }

    if (history.length > 0) { //if there is a history...
        document.getElementsByTagName('button')[].onclick="goBack()"; //assign function "goBack()" to all buttons onClick
    } else {
        die();
    }
</script>

Et quelque part en HTML:

<button value="Button1"> //These buttons have no action
<button value="Button2">

ÉDITER:

Ce que vous pouvez également faire est de rechercher ce que les navigateurs prennent en charge la fonction de retour (je pense qu'ils le font tous) et d'utiliser l'objet de détection de navigateur JavaScript standard trouvé et décrit en détail sur cette page . Ensuite, vous pouvez avoir 2 pages différentes: une pour les "bons navigateurs" compatible avec le bouton retour et une pour les "mauvais navigateurs" leur disant d'aller mettre à jour leur navigateur


2
history.backest une fonction. Vous voulez vérifier si history.length > 0ensuite si c'est revenir avechistory.back()
pixl coder

3
Également []sur une liste de nœuds n'a aucun sens et vous ne pouvez pas affecter une chaîne à un gestionnaire d'événements.
bobince

-8

Vérifiez si window.history.lengthest égal à 0.


6
Pas un bon moyen, puisque history.length ne vous dit pas où vous en êtes dans l'histoire ...
Ron Reiter

@Ron Reiter: Oui, je pense que la réponse principale et les autres commentaires à cette question avaient déjà établi qu'il y a plus d'un an ...
Cristian Sanchez
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.