如何检查用户是否可以返回浏览器历史记录

时间:2010-08-27 21:38:34

标签: javascript

我想使用JavaScript查看是否有历史记录,我的意思是如果浏览器上有后退按钮可用。

22 个答案:

答案 0 :(得分:98)

简短的回答:你不能。

从技术上讲,有一种准确的方法,就是检查财产:

history.previous

但是,它无效。问题在于,在大多数浏览器中,这被视为安全违规,通常只返回未定义

history.length

是其他人建议的财产......
但是,长度不能完全发挥作用,因为它并不表示您所在历史记录中的位置。此外,它并不总是以相同的数字开头。例如,未设置为登录页面的浏览器从0开始,而使用朗读页面的另一个浏览器将从1开始。

alt text

大多数情况下会添加一个调用的链接:

history.back();

 history.go(-1);

并且只是期望如果你不能回去,那么点击链接什么都不做。

答案 1 :(得分:73)

还有另一种检查方法 - 检查推荐人。第一页通常会有一个空的推荐人......

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

答案 2 :(得分:46)

我的代码让浏览器返回一个页面,如果失败则会加载一个后备网址。它还会检测主题标签的更改。

当后退按钮不可用时,后退网址将在500毫秒后加载,因此浏览器有足够的时间加载上一页。在window.history.go(-1);之后加载后备网址会导致浏览器使用后备网址,因为js脚本尚未停止。

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

答案 3 :(得分:11)

这似乎可以解决问题:

function goBackOrClose() {  

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

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

}

调用history.back()然后调用window.close()。如果浏览器能够返回历史记录,则无法进入下一个语句。如果它无法返回,它将关闭窗口。

但请注意,如果通过输入网址到达页面,则firefox不会允许脚本关闭窗口。

答案 4 :(得分:9)

您无法直接检查后退按钮是否可用。您可以查看history.length>0,但如果当前页面还有提前页面,则会成立。 history.length===0时,您只能确定后退按钮无法使用。

如果这还不够好,那么您可以做的就是致电history.back(),如果之后您的页面仍然加载,则后退按钮不可用!当然这意味着如果后退按钮 可用,那么您刚刚离开页面。您不能取消onunload中的导航,因此您可以采取的所有操作来阻止实际发生的事情是从onbeforeunload返回一些内容,这会导致出现一个很大的烦人提示。这不值得。

事实上,对历史做任何事情通常都是一个非常糟糕的想法。历史导航适用于浏览器镶边,而不适用于网页。添加“返回”链接通常会导致更多用户混淆而不是它的价值。

答案 5 :(得分:9)

我是怎么做到的。

我使用了' beforeunload'事件设置布尔值。然后我设置一个超时,以观察' beforeunload'烧成。

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

似乎可以在主流浏览器中使用(到目前为止经过测试的FF,Chrome,IE11)。

答案 6 :(得分:7)

我的项目中使用了一个片段:

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

仅供参考:我使用History.js来管理浏览器历史记录。

为什么要将history.length与数字2进行比较?

因为Chrome的首页被视为浏览器历史记录中的第一项。

history.length和用户行为的可能性很小:

  • 用户在浏览器中打开新的空标签,然后运行一个页面。 history.length = 2我们要在这种情况下禁用back(),因为用户将转到空标签。
  • 用户点击之前的某个链接,在新标签页中打开该页面。 history.length = 1我们又想要禁用back()方法。
  • 最后,用户在重新加载几页后登陆当前页面。可以启用history.length > 2和现在back()

注意:我省略了用户在没有target="_blank"的外部网站点击链接后登陆当前页面的情况。

注意2: document.referrer在您通过键入地址打开网站时以及网站使用ajax加载子页面时为空,因此我在第一种情况下停止检查此值。 / p>

答案 7 :(得分:5)

history.length没用,因为它不会显示用户是否可以返回历史记录。 此外,不同的浏览器使用初始值0或1 - 它取决于浏览器。

工作解决方案是使用$(window).on('beforeunload'事件,但我不确定如果通过ajax加载页面并使用pushState更改窗口历史记录它将起作用。

所以我使用了下一个解决方案:

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

答案 8 :(得分:4)

请注意window.history.length,因为它还包含window.history.forward()

的条目

因此,您可能有window.history.length个条目超过1个,但没有历史记录返回条目。 这意味着如果您触发window.history.back()

,则不会发生任何事情

答案 9 :(得分:1)

实际可行的解决方案

window.history.length == 1

这可在Chrome,Firefox和Edge上使用。 如果要在没有窗口历史记录的情况下隐藏或删除开发的网页上的后退按钮,可以使用以下适用于我的上述三种浏览器的最新版本的JQuery代码。

$(window).load(function() {
        if (window.history.length == 1) {
            $("#back-button").remove();
        }
    })

答案 10 :(得分:1)

我想出了以下方法。它利用onbeforeunload事件来检测浏览器是否开始离开页面。如果它不在某个时间跨度内,它只会重定向到后备。

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

您可以使用goBack("fallback.example.org")调用此功能。

答案 11 :(得分:0)

我在 Angular 中使用 window.history 来处理我网站上的常见问题。

每当用户想要退出常见问题解答时,他们可以点击退出按钮(在后退按钮旁边)

我的这种“退出”策略的逻辑是基于入口 ID,然后返回状态数直到该状态。

然后输入:

  enterState: { navigationId:number } = {navigationId: 1}

  constructor() {
    this.enterState = window.history.state
  }

假装用户浏览常见问题

然后,当用户点击退出按钮时,读取当前状态并计算您的增量:

exitFaq() {
    // when user started in faq, go back to first state, replace it with home and navigate
    if (this.enterState.navigationId === 1) {
      window.history.go((window.history.state.navigationId - 1) * -1)
      this.router.navigateByUrl('/')
      //  non-angular
      //  const obj = {Title: 'Home', Url: '/'}
      //  window.history.replaceState(obj, obj.Title, obj.Url)
    } else {
      window.history.go(this.enterState.navigationId - window.history.state.navigationId - 1)
    }
  }

如您所见,我还使用了用户在 faq 中开始时的回退,在这种情况下,state.navigationId1,我们想要返回,替换第一个状态并显示主页(为此我使用的是 Angular 路由器,但您也可以在处理自己的路由时使用 history.replaceState

供参考:

答案 12 :(得分:0)

var func = function(){ console.log("do something"); };
if(document.referrer.includes(window.location.hostname) && history.length-1 <= 1){
    func();
}
else{
    const currentUrl = window.location.href;
    history.back();
    setTimeout(function(){
        currentUrl === window.location.href && func();
    }, 100);
}

答案 13 :(得分:0)

我正在尝试找到一种解决方案,这是我能得到的最好的解决方案(但效果很好,这是我在这里找到的最简单的解决方案)。

就我而言,我想使用“后退”按钮返回历史记录,但是如果用户打开的第一页是应用程序的子页面,则它将返回主页面。

解决方案是,应用程序一加载,我就对历史记录状态进行了替换:

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

这样,我只需要检查history.state.root后再返回。如果为true,则改为替换历史记录:

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

答案 14 :(得分:0)

以答案herehere为基础。我认为,更结论性的答案只是检查这是否是新标签页中的新页面。

如果页面的历史记录不止一个,那么我们可以返回到当前页面之前的页面。如果没有,则该标签为新打开的标签,我们需要创建一个新标签。

不同地,对于链接的答案,我们不检查referrer,因为新标签仍会包含引荐来源网址。

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

答案 15 :(得分:0)

还有另一个 near 完美解决方案,取自another SO answer

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

有人报告说在使用target="_blank"时它不起作用,但它似乎对我有用。

答案 16 :(得分:0)

浏览器有后退和前进按钮。我提出了这个问题的解决方案。但它会影响浏览器转发操作并导致某些浏览器出错。

它的工作原理如下:如果浏览器打开一个从未打开的新URL,则history.length将会增长。

所以你可以像

一样改变哈希
  location.href = '#__transfer__' + new Date().getTime() 

获取一个从未显示过的url,然后history.length将获得真正的长度。

  var realHistoryLength = history.length - 1

但是,它并不总是运作良好,我不知道为什么,尤其是当url自动快速跳转时。

答案 17 :(得分:-1)

解决方案

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

说明

window.location.pathname将为您提供当前的URI。例如https://domain/question/1234/i-have-a-problem将给出/question/1234/i-have-a-problem。有关更多信息,请参见关于window.location的文档。

接下来,对split()的调用将为我们提供该URI的所有片段。因此,如果我们采用以前的URI,则会有类似["", "question", "1234", "i-have-a-problem"]的内容。有关更多信息,请参见关于String.prototype.split()的文档。

这里对filter()的调用可以过滤出由反斜杠生成的空字符串。基本上,它将仅返回长度大于1(非空字符串)的片段URI。所以我们会有类似["question", "1234", "i-have-a-question"]的东西。可以这样写:

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

有关更多信息,请参见有关Array.prototype.filter()Destructuring assignment的文档。

现在,如果用户尝试返回https://domain/时返回,我们将不会触发if语句,因此也不会触发window.history.back()方法,因此用户将留在我们的网站中。该URL等效于长度为[]的{​​{1}},并且0为false。因此,默默地失败。当然,您可以记录一些内容,或者根据需要执行其他操作。

0 > 0

限制

当然,如果浏览器不支持History API,则此解决方案将不起作用。使用此解决方案之前,请查看文档以了解更多信息。

答案 18 :(得分:-1)

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

答案 19 :(得分:-1)

我使用了一些 PHP 来实现结果。不过有点生锈了。但它应该可以工作。

<?php 
function pref(){ 
  return (isset($_SERVER['HTTP_REFERER'])) ? true : '';
}
?>
<html>
<body>

<input type="hidden" id="_pref" value="<?=pref()?>">

<button type="button" id="myButton">GoBack</button>

<!-- Include jquery library -->
<script> 
  if (!$('#_pref').val()) { 
    $('#myButton').hide() // or $('#myButton').remove()
  } 
</script>
</body>
</html>

答案 20 :(得分:-6)

我不确定这是否有效且完全未经测试,但请尝试以下方法:

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

HTML中的某个地方:

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

编辑:

您还可以做的是研究哪些浏览器支持后退功能(我认为他们都这样做)并使用this page上发现的标准JavaScript浏览器检测对象并进行详细描述。然后你可以有2个不同的页面:一个用于与后退按钮兼容的“好浏览器”,另一个用于“坏浏览器”,告诉他们更新浏览器

答案 21 :(得分:-7)

检查window.history.length是否等于0.