So überprüfen Sie, ob der Benutzer in den Browserverlauf zurückkehren kann oder nicht

151

Ich möchte mit JavaScript sehen, ob es einen Verlauf gibt oder nicht. Ich meine, ob die Schaltfläche "Zurück" im Browser verfügbar ist oder nicht.

Ryan
quelle

Antworten:

118

Kurze Antwort: Das kannst du nicht.

Technisch gibt es einen genauen Weg, der die Eigenschaft überprüfen würde:

history.previous

Es wird jedoch nicht funktionieren. Das Problem dabei ist, dass dies in den meisten Browsern als Sicherheitsverletzung angesehen wird und normalerweise nur undefiniert zurückgegeben wird .

history.length

Ist eine Eigenschaft, die andere vorgeschlagen haben ...
Die Länge funktioniert jedoch nicht vollständig, da sie nicht angibt, wo Sie sich im Verlauf befinden. Außerdem beginnt es nicht immer mit derselben Nummer. Ein Browser, für den beispielsweise keine Zielseite festgelegt ist, beginnt bei 0, während ein anderer Browser, der eine Zielseite verwendet, bei 1 startet.

Alt-Text

Meistens wird ein Link hinzugefügt, der Folgendes aufruft:

history.back();

oder

 history.go(-1);

und es wird nur erwartet, dass, wenn Sie nicht zurückgehen können, das Klicken auf den Link nichts bewirkt.

McAden
quelle
Dies ist eine gute Information, aber sie löst das Problem nicht. Es wäre, einen Code auszuarbeiten, der tatsächlich in jedem Browser funktioniert. Möglicherweise ein Code, der zuerst den von Ihnen verwendeten Browser überprüft.
Santiago Bendavid
5
Was ich sage ist, dass es keine endgültige Antwort gibt. Sie sagen die Vor- und Nachteile jedes Ansatzes, aber nicht, wie Sie ein Skript erhalten, das überprüft, welchen Browser Sie verwenden, und den einen oder anderen Code bedingt ausführt.
Santiago Bendavid
Darf ich wissen, was Sie unter "Das Problem dabei ist, dass dies in den meisten Browsern als Sicherheitsverletzung angesehen wird" verstehen. Ein anderer Benutzer in einem anderen Thread wies ebenfalls darauf hin, dass das Abrufen des Browserverlaufs des Clients die Sicherheit verletzt, dies jedoch nicht erklärt warum ist das so. Kann jemand ein Beispiel geben, was die Sicherheitsbedrohungen sind?
Kevin Chandra
Eine Website sollte nicht in der Lage sein, den Verlauf eines Benutzers zu kennen, der indirekte persönliche Informationen enthalten könnte. Eine Site kann Tracking / Cookies verwenden, um zu wissen, was der Benutzer auf der Site selbst tut, aber sie sollten beispielsweise nicht herausfinden dürfen, welche Bank ich benutze, welche Schule meine Kinder besuchen usw. Die Browser erlauben keinen Zugriff auf diese Eigenschaft
McAden
84

Es gibt eine andere Möglichkeit zu überprüfen - überprüfen Sie den Referrer. Die erste Seite hat normalerweise einen leeren Referrer ...

if (document.referrer == "") {
    window.close()
} else {
    history.back()
}
Ron Reiter
quelle
2
Referrer kann aus Datenschutzgründen ausgeblendet werden.
Kornel
11
Der Referrer ist immer leer, wenn eine Seite nicht durch einen Link geladen wurde, sondern indem die URL in die Adressleiste eingegeben oder ein Lesezeichen geladen wurde. Solche Seiten können jedoch einen Verlauf haben, wenn der Browser-Tab / das Browser-Fenster zuvor eine andere Seite geladen hat!
Ygoe
1
Aber ist anwendbare Lösung für die Navigation über die mehrseitige Website
Dan
36
Funktioniert nicht, wenn ein Fenster mit target = "_ blank" geöffnet wurde, um ein neues Fenster zu erzwingen. Die Zurück-Schaltfläche im Browser funktioniert nicht, aber es wird ein document.referrer
Mike_K
3
Dies funktioniert nicht, wenn Sie von einer sicheren Seite (HTTPS) zu einer unsicheren Seite (HTTP) wechseln, da dadurch der Verweis entfernt wird.
Kevin Borders
54

Mein Code ließ den Browser eine Seite zurückgehen, und wenn dies fehlschlägt, wird eine Fallback-URL geladen. Es erkennt auch Änderungen an Hashtags.

Wenn die Schaltfläche "Zurück" nicht verfügbar war, wird die Fallback-URL nach 500 ms geladen, sodass der Browser genügend Zeit hat, um die vorherige Seite zu laden. Das Laden der Fallback-URL direkt danach window.history.go(-1);würde dazu führen, dass der Browser die Fallback-URL verwendet, da das js-Skript noch nicht gestoppt wurde.

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);
}
redelschaap
quelle
6
Ich denke, das ist wirklich der Kern der Frage, warum sich eine Person interessiert und was tatsächlich zuverlässig und konsequent dagegen getan werden kann.
Chris Marisic
1
Dies funktionierte, bis ich die URL, unter der sich der Zurück-Button befindet, in einen neuen Tab in Chrome einfügte. Durch Klicken auf die Schaltfläche "Zurück" wurde eine leere Registerkarte angezeigt. :(
Karlingen
2
Dies ist das Standardverhalten von Chrome. Sie haben die Seite "besucht" chrome://newtabund können so in die Geschichte zurückgehen.
Redelschaap
Seien Sie vorsichtig damit, da Sie bei einer langsamen Netzwerkverbindung ziemlich regelmäßig auf die Fallback-URL zugreifen.
am
14

Hier ist, wie ich es gemacht habe.

Ich habe das Ereignis 'beforeunload' verwendet , um einen Booleschen Wert festzulegen . Dann habe ich eine Zeitüberschreitung festgelegt, um zu beobachten, ob die Vorabladung ausgelöst wurde.

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

Scheint in gängigen Browsern zu funktionieren (bisher FF, Chrome, IE11 getestet).

Toni Feistauer
quelle
1
Dies ist bei weitem die beste Antwort auf die Frage. Sie können ganz einfach ersetzen window.location.href = fallbackmit window.close()und es funktioniert auch.
Vitani
13

Es gibt einen Ausschnitt, den ich in meinen Projekten verwende:

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

Zu Ihrer Information: Ich verwende History.js , um den Browserverlauf zu verwalten.


Warum sollte man history.length mit Nummer 2 vergleichen?

Weil die Startseite von Chrome als erstes Element im Browserverlauf gezählt wird.


Es gibt nur wenige Möglichkeiten history.lengthund das Verhalten des Benutzers:

  • Der Benutzer öffnet eine neue leere Registerkarte im Browser und führt dann eine Seite aus.history.length = 2und wir möchten back()in diesem Fall deaktivieren , da der Benutzer zum leeren Tab wechselt.
  • Der Benutzer öffnet die Seite in einem neuen Tab, indem er irgendwo zuvor auf einen Link klickt. history.length = 1und wieder wollen wir deaktivierenback() Methode .
  • Und schließlich landet der Benutzer auf der aktuellen Seite, nachdem er einige Seiten neu geladen hat . history.length > 2und jetzt back()kann aktiviert werden.

Hinweis: Ich lasse den Fall aus, wenn der Benutzer auf der aktuellen Seite landet, nachdem er auf den Link von einer externen Website ohne geklickt hattarget="_blank" .

Hinweis 2: document.referrer ist leer, wenn Sie eine Website durch Eingabe ihrer Adresse öffnen und wenn die Website Ajax zum Laden von Unterseiten verwendet. Daher habe ich die Überprüfung dieses Werts im ersten Fall eingestellt.

Gregmatys
quelle
Dieser Ansatz hat bei mir sehr gut funktioniert. Ich speichere tatsächlich statische Fallback-Links für meine Seiten, die ich für den Fallback verwende.
Greg Blass
Aber wenn Sie zurückgehen, wird sich die Länge der Geschichte nicht ändern. Also funktioniert es nicht richtig
Ciprian Mocanu
Du hast leider recht. Ich benutze dieses Snippet nur mit "One-Step-Back" -Struktur ...
Gregmatys
12

das scheint den Trick zu tun:

function goBackOrClose() {  

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

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

}

Rufen Sie history.back () und dann window.close () auf. Wenn der Browser in den Verlauf zurückkehren kann, kann er nicht zur nächsten Anweisung gelangen. Wenn es nicht zurückkehren kann, wird das Fenster geschlossen.

Beachten Sie jedoch, dass Firefox dem Skript nicht erlaubt, das Fenster zu schließen, wenn die Seite durch Eingabe einer URL erreicht wurde.

xtrahelp.com
quelle
3
Ich habe festgestellt, dass dies nur funktioniert, wenn ich ein setTimeout mit einer Verzögerung von einigen hundert Millisekunden verwende, bevor ich versuche, die nächste Anweisung auszuführen. Andernfalls wird es trotzdem ausgeführt, nachdem history.back ()
Ken Fehling
Ich habe das nicht persönlich erlebt, welcher Browser war das?
xtrahelp.com
Ich hatte gut mit der setTimeout-Funktion in der folgenden Antwort gearbeitet. Beispiel: setTimeout (function () {window.close ()}, 400);
Gilchris
2
window.close()wird von vielen modernen Browsern als Sicherheitsrisiko angesehen. Einige lassen es einfach nicht zu.
Rudi Kershaw
Sie können alles nach window.history.back () tun; window.close (); ist nur ein Beispiel
Hariszaman
9

Sie können nicht direkt überprüfen, ob die Zurück-Schaltfläche verwendet werden kann. Sie können sich das ansehen history.length>0, aber das gilt auch, wenn der aktuellen Seite Seiten voraus sind . Sie können nur dann sicher sein , dass die Zurück-Taste unbrauchbar ist, wenn history.length===0.

Wenn das nicht gut genug ist, können Sie nur anrufen history.back()und wenn Ihre Seite danach noch geladen wird, ist die Zurück-Schaltfläche nicht verfügbar! Das bedeutet natürlich, wenn die Zurück - Taste ist verfügbar, haben navigiert Sie gerade von der Seite entfernt. Sie dürfen die Navigation nicht abbrechen. onunloadAlles, was Sie tun können, um zu verhindern, dass das Zurück passiert, ist, etwas zurückzugeben onbeforeunload, was zu einer großen nervigen Eingabeaufforderung führt. Es lohnt sich nicht.

Tatsächlich ist es normalerweise eine wirklich schlechte Idee, irgendetwas mit der Geschichte zu tun. Die Verlaufsnavigation ist für Browser-Chrome und nicht für Webseiten. Das Hinzufügen von "Zurück" -Links führt normalerweise zu mehr Verwirrung bei den Benutzern, als es wert ist.

Bobince
quelle
2
in Bezug auf die Länge - auch dann nicht in allen Browsern. Einige Browser zählen die aktuelle Seite als Verlaufselement und beginnen bei 1. Sie müssten die Browsererkennung einbeziehen.
McAden
Eigentlich dachte ich es war immer 1! Das 0war ein Brainfart, ich dachte, Browser würden immer mit 1oder mehr antworten . Es stellt sich heraus, dass Opera und IE anders denken - guter Fang.
Bobince
1
"Verlaufsnavigation ist für Browser-Chrome, nicht für Webseiten" - Einverstanden
Brian
9

Seien Sie vorsichtig mit, window.history.lengthda es auch Einträge für enthältwindow.history.forward()

Sie haben also vielleicht window.history.lengthmehr als 1 Einträge, aber keine Einträge für den Verlauf zurück. Dies bedeutet, dass nichts passiert, wenn Sie schießenwindow.history.back()

Blitzlord
quelle
5

history.lengthist nutzlos, da nicht angezeigt wird, ob der Benutzer in den Verlauf zurückkehren kann. Auch verschiedene Browser verwenden die Anfangswerte 0 oder 1 - dies hängt vom Browser ab.

Die funktionierende Lösung besteht darin, $(window).on('beforeunload'event zu verwenden , aber ich bin nicht sicher, ob es funktioniert, wenn die Seite über Ajax geladen wird und pushState verwendet, um den Fensterverlauf zu ändern.

Also habe ich die nächste Lösung verwendet:

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);
Gromo
quelle
Funktioniert bei mir so: function goBackOrTo (targetUrl) {var currentUrl = window.location.href; window.history.go (-1); setTimeout (function () {// Wenn der Speicherort in 800 ms nicht geändert wurde, gibt es keinen Verlauf zurück if (currentUrl === window.location.href) {// Weiterleitung zum Site-Stammfenster window.location.href = targetUrl; }}, 800); }
Alfonx
2

Ich habe mir den folgenden Ansatz ausgedacht. Es verwendet das Ereignis onbeforeunload, um festzustellen, ob der Browser die Seite verlässt oder nicht. Wenn dies in einer bestimmten Zeitspanne nicht der Fall ist, wird nur zum Fallback umgeleitet.

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

Sie können diese Funktion mit aufrufen goBack("fallback.example.org").

Pascal Raszyk
quelle
1
Das gefällt mir am besten, ich habe gerade windows.onbeforeunloadzum Ereignis-Listener gewechselt , window.addEventListener("beforeunload", function (event) { useFallback = false; });damit window.onbeforeunload nicht überschrieben wird.
MiChAeLoKGB
2

Aufbauend auf der Antwort hier und hier . Ich denke, die schlüssigere Antwort ist nur zu überprüfen, ob dies eine neue Seite in einem neuen Tab ist.

Wenn der Verlauf der Seite mehr als eins umfasst, können wir zur Seite vor der aktuellen Seite zurückkehren. Wenn nicht, ist die Registerkarte eine neu geöffnete Registerkarte und wir müssen eine neue Registerkarte erstellen.

Anders als bei den verknüpften Antworten suchen wir nicht nach einem, referrerda ein neuer Tab immer noch einen Verweis hat.

if(1 < history.length) {
    history.back();
}
else {
    window.close();
}
atw
quelle
1
Danke dir. Du hast meinen Tag gerettet:).
Bijay Yadav
1

Es gibt eine andere nahezu perfekte Lösung, die einer anderen SO-Antwort entnommen ist :

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

Jemand berichtete, dass es bei der Verwendung nicht funktioniert, target="_blank"aber es scheint für mich in Chrome zu funktionieren.

Yonn Trimoreau
quelle
0

Der Browser verfügt über eine Vor- und Zurück-Schaltfläche. Ich habe eine Lösung für diese Frage gefunden. Dies wirkt sich jedoch auf die Weiterleitungsaktion des Browsers aus und führt bei einigen Browsern zu Fehlern.

Das funktioniert so: Wenn der Browser eine neue URL öffnet, die noch nie geöffnet wurde, wächst die history.length.

So können Sie Hash wie ändern

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

Um eine nie angezeigte URL zu erhalten, erhält history.length die wahre Länge.

  var realHistoryLength = history.length - 1

Aber es funktioniert nicht immer gut und ich weiß nicht warum, besonders wenn die URL automatisch automatisch springt.

Honchy Gan
quelle
0

Ich habe versucht, eine Lösung zu finden, und dies ist das Beste, was ich bekommen konnte (aber es funktioniert großartig und es ist die einfachste Lösung, die ich selbst hier gefunden habe).

In meinem Fall wollte ich mit einem Zurück-Button zum Verlauf zurückkehren, aber wenn die erste Seite, die der Benutzer öffnete, eine Unterseite meiner App war, würde sie zur Hauptseite zurückkehren.

Die Lösung war, sobald die App geladen ist, habe ich nur den Verlaufsstatus ersetzt:

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

Auf diese Weise muss ich nur überprüfen, history.state.rootbevor ich zurückgehe. Wenn das stimmt, ersetze ich stattdessen eine Historie:

if(history.state && history.state.root)
    history.replaceState( {root: true}, '', '/')
else
    history.back() 
Maxwell sc
quelle
Ich glaube nicht, dass es einen anderen guten Anwendungsfall gibt. Vielleicht ist das keine gute Idee, wenn Sie den Verlauf außerhalb Ihrer App überprüfen möchten.
Maxwell sc
-1
var fallbackUrl = "home.php";
if(history.back() === undefined)
    window.location.href = fallbackUrl;
Rejeesh Prarath
quelle
das sieht super einfach aus?! wird es auf den verschiedenen Browsern getestet?
Benzkji
in Chrome history.back()ist undefinednur auf leerer Registerkarte
Gregmatys
-2

Lösung

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

Erklärung

window.location.pathnamegibt Ihnen den aktuellen URI. Zum Beispiel https://domain/question/1234/i-have-a-problemwird geben /question/1234/i-have-a-problem. Weitere Informationen finden Sie in der Dokumentation zu window.location .

Als nächstes split()gibt uns der Aufruf von alle Fragmente dieser URI. Wenn wir also unsere vorherige URI verwenden, haben wir so etwas wie ["", "question", "1234", "i-have-a-problem"]. Weitere Informationen finden Sie in der Dokumentation zu String.prototype.split () .

Der Aufruf von filter()dient dazu, die durch den Schrägstrich erzeugte leere Zeichenfolge herauszufiltern. Grundsätzlich wird nur der Fragment-URI zurückgegeben, dessen Länge größer als 1 ist (nicht leere Zeichenfolge). Also hätten wir so etwas wie ["question", "1234", "i-have-a-question"]. Dies hätte so geschrieben werden können:

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

Weitere Informationen finden Sie in der Dokumentation zu Array.prototype.filter () und in der Destructuring-Zuweisung .

Wenn der Benutzer versucht, während der https://domain/Aktivierung zurückzukehren, wird die if-Anweisung nicht ausgelöst, und die window.history.back()Methode wird nicht ausgelöst , damit der Benutzer auf unserer Website bleibt. Diese URL entspricht []einer URL von 0und 0 > 0ist falsch. Daher stillschweigend scheitern. Natürlich können Sie etwas protokollieren oder eine andere Aktion ausführen, wenn Sie möchten.

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

Einschränkungen

Natürlich funktioniert diese Lösung nicht, wenn der Browser die Verlaufs- API nicht unterstützt . Lesen Sie die Dokumentation, um mehr darüber zu erfahren, bevor Sie diese Lösung verwenden.

Amin NAIRI
quelle
-5

Ich bin nicht sicher, ob dies funktioniert und es ist völlig ungetestet, aber versuchen Sie Folgendes:

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

Und irgendwo in HTML:

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

BEARBEITEN:

Sie können auch untersuchen, welche Browser die Back-Funktion unterstützen (ich glaube, alle tun dies) und das Standardobjekt zur Erkennung von JavaScript-Browsern verwenden, das auf dieser Seite gefunden und ausführlich beschrieben wird . Dann können Sie zwei verschiedene Seiten haben: eine für die "guten Browser", die mit der Zurück-Schaltfläche kompatibel sind, und eine für die "schlechten Browser", die ihnen sagen, dass sie ihren Browser aktualisieren sollen

Latze
quelle
2
history.backist eine Funktion. Sie möchten überprüfen, ob history.length > 0dann, wenn es zurück geht mithistory.back()
Pixl-Codierer
3
Auch []auf einer NodeList macht es keinen Sinn, und Sie können einem Event-Handler keine Zeichenfolge zuweisen.
Bobince
-8

Überprüfen Sie, ob window.history.lengthgleich 0 ist.

Cristian Sanchez
quelle
6
Kein guter Weg, da history.length Ihnen nicht sagt, wo Sie in der Geschichte sind ...
Ron Reiter
@ Ron Reiter: Ja, ich denke, die Top-Antwort und andere Kommentare für diese Frage hatten bereits vor über einem Jahr festgestellt ...
Cristian Sanchez