如何使用javascript停止浏览器后退按钮

时间:2012-09-12 05:09:11

标签: javascript browser

我正在使用php进行在线测验应用。我想限制用户重新参加考试。 我尝试了以下脚本,但它停止了我的计时器。 我该怎么办?

我已经包含了源代码。 计时器存储在cdtimer.js

<script type="text/javascript">
        window.history.forward();
        function noBack()
        {
            window.history.forward();
        }
</script>
<body onLoad="noBack();" onpageshow="if (event.persisted) noBack();" onUnload="">

我有一个考试计时器,它从 mysql 值开始考试。计时器会相应地启动,但是当我输入代码以禁用后退按钮时它会停止。我的问题是什么?

35 个答案:

答案 0 :(得分:142)

禁用后退按钮无法正常工作的原因有很多。最好的办法是警告用户:

window.onbeforeunload = function() { return "Your work will be lost."; };

此页面列出了可以尝试禁用后退按钮的多种方式,但没有一种方法可以保证:

http://www.irt.org/script/311.htm

答案 1 :(得分:112)

覆盖Web浏览器的默认行为通常是一个坏主意。出于安全原因,客户端脚本没有足够的权限来执行此操作。

也有一些类似的问题,

不能实际上禁用浏览器后退按钮。但是,您可以使用您的逻辑进行魔术,以防止用户导航回来,这会产生一种类似于禁用的印象。方法如下,请查看以下代码段。

(function (global) { 

    if(typeof (global) === "undefined") {
        throw new Error("window is undefined");
    }

    var _hash = "!";
    var noBackPlease = function () {
        global.location.href += "#";

        // making sure we have the fruit available for juice (^__^)
        global.setTimeout(function () {
            global.location.href += "!";
        }, 50);
    };

    global.onhashchange = function () {
        if (global.location.hash !== _hash) {
            global.location.hash = _hash;
        }
    };

    global.onload = function () {            
        noBackPlease();

        // disables backspace on page except on input fields and textarea..
        document.body.onkeydown = function (e) {
            var elm = e.target.nodeName.toLowerCase();
            if (e.which === 8 && (elm !== 'input' && elm  !== 'textarea')) {
                e.preventDefault();
            }
            // stopping event bubbling up the DOM tree..
            e.stopPropagation();
        };          
    }

})(window);

这是纯JavaScript,所以它适用于大多数浏览器。它还会禁用退格键,但键会在input字段和textarea内正常工作。

推荐设置:

将此代码段放在单独的脚本中,并将其包含在您希望此行为的页面上。在当前设置中,它将执行DOM的onload事件,这是此代码的理想入口点。

<强> Working DEMO!

在以下浏览器中进行测试和验证,

  • 铬。
  • 火狐。
  • IE(8-11)和Edge。
  • Safari浏览器。

答案 2 :(得分:64)

<script>
window.location.hash="no-back-button";
window.location.hash="Again-No-back-button";//again because google chrome don't insert first hash into history
window.onhashchange=function(){window.location.hash="no-back-button";}
</script> 

答案 3 :(得分:50)

我遇到过这个问题,需要一个能够在各种浏览器上正常工作的解决方案,包括Mobile Safari (iOS9在发布时)。没有一个解决方案是正确的。我提供以下内容(在IE11,FireFox,Chrome和Safari上测试):

history.pushState(null, document.title, location.href);
window.addEventListener('popstate', function (event)
{
  history.pushState(null, document.title, location.href);
});

请注意以下事项:

  • history.forward()(我的旧解决方案)无法在Mobile Safari上运行---它似乎什么都不做(即用户仍然可以返回)。 history.pushState()确实适用于所有这些。
  • history.pushState()的第三个参数是 url 。传递像'no-back-button''pagename'这样的字符串的解决方案似乎工作正常,直到您在页面上尝试刷新/重新加载,此时浏览器尝试时会生成“找不到页面”错误找到一个页面作为其Url。 (浏览器也可能在页面上的地址栏中包含该字符串,这很难看。)location.href应该用于网址。
  • history.pushState()的第二个参数是标题。环顾网络,大多数地方都说它“未使用”,所有解决方案都通过了null。但是,至少在Mobile Safari中,将页面的Url放入用户可以访问的历史记录下拉列表中。但是当它为正常的页面访问添加一个条目时,它会放入 title ,这是更好的选择。因此,传递document.title会导致相同的行为。

答案 4 :(得分:25)

此代码将禁用支持HTML5 History API的现代浏览器的后退按钮。在正常情况下,按下后退按钮会返回上一页。如果使用history.pushState(),则开始向当前页面添加额外的子步骤。它的工作方式是,如果你使用history.pushState()三次,然后开始按下后退按钮,前三次它将导航回这些子步骤,然后第四次它将返回到上一页。

如果将此行为与popstate事件上的事件侦听器结合使用,则实际上可以设置无限循环的子状态。所以,你加载页面,按子状态,然后点击后退按钮,弹出一个子状态,并推动另一个,所以如果你再次按下后退按钮,它将永远不会用完子状态推。如果您认为有必要禁用后退按钮,那么这将帮助您实现目标。

history.pushState(null, null, 'no-back-button');
window.addEventListener('popstate', function(event) {
  history.pushState(null, null, 'no-back-button');
});

答案 5 :(得分:10)

这是我完成它的方式。 怪异地改变了window.location并没有在chrome和safari中做得很好。 发现location.hash没有在chrome和safari的历史记录中创建条目。所以你必须使用pushstate。 这适用于所有浏览器。

    history.pushState({ page: 1 }, "title 1", "#nbb");
    window.onhashchange = function (event) {
        window.location.hash = "nbb";

    };

答案 6 :(得分:9)

<html>
<head>
    <title>Disable Back Button in Browser - Online Demo</title>
    <style type="text/css">
        body, input {
            font-family: Calibri, Arial;
        }
    </style>
    <script type="text/javascript">
        window.history.forward();
        function noBack() {
            window.history.forward();
        }
    </script>
</head>
<body onload="noBack();" onpageshow="if (event.persisted) noBack();" onunload="">
    <H2>Demo</H2>
    <p>This page contains the code to avoid Back button.</p>
    <p>Click here to Goto <a href="noback.html">NoBack Page</a></p>
</body>
</html>

答案 7 :(得分:8)

This article on jordanhollinger.com是我觉得最好的选择。与Razor的答案类似,但更清楚一点。代码如下;完全归功于Jordan Hollinger:

之前的页面:

<a href="/page-of-no-return.htm#no-back>You can't go back from the next page</a>

不归路的JavaScript页面:

// It works without the History API, but will clutter up the history
var history_api = typeof history.pushState !== 'undefined'

// The previous page asks that it not be returned to
if ( location.hash == '#no-back' ) {
  // Push "#no-back" onto the history, making it the most recent "page"
  if ( history_api ) history.pushState(null, '', '#stay')
  else location.hash = '#stay'

  // When the back button is pressed, it will harmlessly change the url
  // hash from "#stay" to "#no-back", which triggers this function
  window.onhashchange = function() {
    // User tried to go back; warn user, rinse and repeat
    if ( location.hash == '#no-back' ) {
      alert("You shall not pass!")
      if ( history_api ) history.pushState(null, '', '#stay')
      else location.hash = '#stay'
    }
  }
}

答案 8 :(得分:8)

Chrome 79 中,没有一个最受好评的答案对我有用。在75版之后,Chrome似乎更改了其有关“后退”按钮的行为。请参见此处:

https://support.google.com/chrome/thread/8721521?hl=en

但是,在该Google线程中,Azrulmukmin Azmi在最后提供的答案确实有效。这是他的解决方案。

<script>
    history.pushState(null, document.title, location.href);
    history.back();
    history.forward();
    window.onpopstate = function () {
        history.go(1);
    };
</script>

Chrome的问题在于它不会触发onpopstate事件 除非您执行浏览器操作(即致电history.back)。这就是为什么 我已将它们添加到脚本中。

我不完全理解他写的内容,但显然现在需要额外的history.back() / history.forward()才能阻止Chrome 75+中的Back。

答案 9 :(得分:8)

    history.pushState(null, null, location.href);
    window.onpopstate = function () {
        history.go(1);
    };

答案 10 :(得分:7)

此代码已在最新的Chrome和Firefox浏览器上进行了测试。

"prettier":{
  "arrowParens": "avoid",
  "bracketSpacing": true,
  "htmlWhitespaceSensitivity": "css",
  "insertPragma": false,
  "jsxBracketSameLine": false,
  "jsxSingleQuote": false,
  "printWidth": 140,
  "proseWrap": "preserve",
  "quoteProps": "as-needed",
  "requirePragma": false,
  "semi": true,
  "singleQuote": false,
  "tabWidth": 2,
  "trailingComma": "none",
  "useTabs": false,
  "vueIndentScriptAndStyle": false,
  "rangeStart": 0
}

答案 11 :(得分:6)

history.pushState(null, null, document.URL);
window.addEventListener('popstate', function () {
    history.pushState(null, null, document.URL);
});

此javascript不允许任何用户返回(可在Chrome,FF,IE,Edge中运行)

答案 12 :(得分:5)

轻松尝试:

history.pushState(null, null, document.title);
window.addEventListener('popstate', function () {
    history.pushState(null, null, document.title);
});

答案 13 :(得分:3)

非常简单干净的功能,可以在不干扰页面的情况下打破后退箭头。

<强>优点:

  • 即时加载并恢复原始哈希值,这样用户就不会因URL明显改变而分心。
  • 用户仍然可以退回10次(这是一件好事),但不是意外
  • 与使用onbeforeunload
  • 的其他解决方案一样,没有用户干扰
  • 它只运行一次,并且在您使用它来跟踪状态时不会干扰进一步的哈希操作
  • 恢复原始哈希,几乎看不见。
  • 使用setInterval因此它不会破坏缓慢的浏览器并始终有效。
  • 纯Javascript,不需要HTML5历史记录,无处不在。
  • 不显眼,简单,并与其他代码配合使用。
  • 不使用unbeforeunload使用模态对话框中断用户。
  • 它没有大惊小怪。

注意:其他一些解决方案使用onbeforeunload。请不要为此目的使用onbeforeunload,当用户尝试关闭窗口,点击后退等时会弹出一个对话框。onbeforeunload等模式通常只适用于罕见的情况,例如他们实际上在屏幕上进行了更改并且没有保存它们,而不是为此目的。

如何运作

  1. 执行页面加载
  2. 保存您的原始哈希值(如果在网址中)。
  3. 按顺序将#/ noop / {1..10}附加到哈希
  4. 恢复原始哈希
  5. 就是这样。没有进一步的混乱,没有背景事件监控,没有别的。

    一秒钟使用

    要部署,只需将其添加到您的页面或JS中的任何位置:

    <script>
    /* break back button */                                                                        
    window.onload=function(){                                                                      
      var i=0; var previous_hash = window.location.hash;                                           
      var x = setInterval(function(){                                                              
        i++; window.location.hash = "/noop/" + i;                                                  
        if (i==10){clearInterval(x);                                                               
          window.location.hash = previous_hash;}                                                   
      },10);
    }
    </script>
    

答案 14 :(得分:3)

用于限制浏览器后退事件

window.history.pushState(null, "", window.location.href);
window.onpopstate = function () {
    window.history.pushState(null, "", window.location.href);
};

答案 15 :(得分:2)

这似乎对我们有用,可以禁用浏览器上的后退按钮,以及退格按钮带你回来。

history.pushState(null, null, $(location).attr('href'));
    window.addEventListener('popstate', function () {
        history.pushState(null, null, $(location).attr('href'));
    });

答案 16 :(得分:2)

反应

对于React项目中的模态组件,模态的 open close ,控制浏览器返回是必要的动作。

  • id mol type x y z 100000 ITEM: NUMBER OF ATOMS 3000 ITEM: BOX BOUNDS pp pp pp 4.8659189006091452e-02 3.0951340810994285e+01 4.8659189006091452e-02 3.0951340810994285e+01 4.8659189006091452e-02 3.0951340810994285e+01 ITEM: ATOMS id mol type x y z 2325 775 1 4.5602 4.35401 4.16348 718 240 2 4.91829 3.19545 7.30041 2065 689 2 6.51189 1.25778 5.11324 639 213 1 6.84357 5.10011 0.530398 720 240 1 5.46433 3.36715 6.48044 694 232 2 0.107046 3.3119 7.42581 1855 619 2 6.17236 4.57208 5.02607 1856 619 1 6.65988 5.13298 5.69518 :浏览器后退按钮功能的停止,还获得了回调功能。此回调函数是您想做什么

    stopBrowserBack
  • const stopBrowserBack = callback => { window.history.pushState(null, "", window.location.href); window.onpopstate = () => { window.history.pushState(null, "", window.location.href); callback(); }; }; :浏览器后退按钮功能的复兴:

    startBrowserBack

项目中的用法:

const startBrowserBack = () => {
  window.onpopstate = undefined;
  window.history.back();
};

答案 17 :(得分:2)

我遇到React(类组件)这个问题。

我很容易地解决了这个问题:

componentDidMount() {
    window.addEventListener("popstate", e => {
        this.props.history.goForward();
    }
}

我使用了HashRouter中的react-router-dom

答案 18 :(得分:1)

尝试这样做以防止IE中的退格按钮,默认情况下作为“后退”:

<script language="JavaScript">
$(document).ready(function() {
$(document).unbind('keydown').bind('keydown', function (event) {
    var doPrevent = false;


    if (event.keyCode === 8 ) {
        var d = event.srcElement || event.target;
        if ((d.tagName.toUpperCase() === 'INPUT' && 
             (
                 d.type.toUpperCase() === 'TEXT' ||
                 d.type.toUpperCase() === 'PASSWORD' || 
                 d.type.toUpperCase() === 'FILE' || 
                 d.type.toUpperCase() === 'EMAIL' || 
                 d.type.toUpperCase() === 'SEARCH' || 
                 d.type.toUpperCase() === 'DATE' )
             ) || 
             d.tagName.toUpperCase() === 'TEXTAREA') {
            doPrevent = d.readOnly || d.disabled;
        }
        else {

            doPrevent = true;
        }
    }

    if (doPrevent) {
        event.preventDefault();
    }

    try {
        document.addEventListener('keydown', function (e) {
               if ((e.keyCode === 13)){
                  // alert('Enter keydown');
                   e.stopPropagation();
                   e.preventDefault();
               }



           }, true);
        } catch (err) {}
    });
});
</script>

答案 19 :(得分:1)

我相信完美而又完美的解决方案实际上非常简单,我现在使用了很多年。

它基本上分配了窗口&#34; onbeforeunload&#34;活动以及正在进行的文件&#39; mouseenter&#39; /&#39; mouseleave&#39;事件,因此警报仅在点击位于文档范围之外时触发(然后可以是浏览器的后退或前进按钮)

$(document).on('mouseenter', function(e) { 
        window.onbeforeunload = null; 
    }
);

$(document).on('mouseleave', function(e) { 
        window.onbeforeunload = function() { return "You work will be lost."; };
    }
);

答案 20 :(得分:1)

<script language="JavaScript">
    javascript:window.history.forward(1);
</script>

答案 21 :(得分:1)

在现代浏览器中,这似乎可行:

// https://developer.mozilla.org/en-US/docs/Web/API/History_API
let popHandler = () => {
  if (confirm('Go back?')) {
    window.history.back() 
  } else {
    window.history.forward()
    setTimeout(() => {
      window.addEventListener('popstate', popHandler, {once: true})
    }, 50) // delay needed since the above is an async operation for some reason
  }
}
window.addEventListener('popstate', popHandler, {once: true})
window.history.pushState(null,null,null)

答案 22 :(得分:1)

   <script src="~/main.js" type="text/javascript"></script>
    <script type="text/javascript">
        window.history.forward();
        function noBack() { window.history.forward(); } </script>

答案 23 :(得分:0)

这有效:

$(document).ready(async function ()
{
    history.pushState(null, null, location.href);
    window.onpopstate = function () {
        history.go(1);
    };
}

答案 24 :(得分:0)

这是 Google 查询“禁用后退按钮”的第一次点击。我的用例与最初发布的问题略有不同。我需要为已登录安全网站的用户“禁用后退按钮”(即防止用户注销,然后另一个用户能够通过点击后退按钮查看前一个用户的信息)。< /p>

简而言之,这里的目标是防止用户在登录用户注销后看到应用程序页面。

这可以通过将下面显示的代码添加到经过身份验证的应用程序中的页面来实现。

此处提供了使用 Apache Shiro 的完整示例:

https://github.com/NACHC-CAD/web-security-example/releases/tag/v2.0.0

<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="-1" />
<meta http-equiv="CACHE-CONTROL" content="NO-CACHE" />

<script>
    if(performance.navigation.type == 2){
        console.log("Doing reload");   
        location.reload(true);
        console.log("Done with reload");
    }
    console.log("Script loaded.")
</script>

答案 25 :(得分:0)

禁用浏览器的后退按钮

<script type="text/javascript">
        history.go(1);
</script>

答案 26 :(得分:0)

这段代码是完整的javascript。 将其放在您的主页或您需要的任何内容上,当有人返回时,它会将他们带到他们之前所在的页面。

<script type="text/javascript"> 
        function preventBack() { 
            window.history.forward();  
        } 
          
        setTimeout("preventBack()", 0); 
          
        window.onunload = function () { null }; 
    </script>

答案 27 :(得分:0)

此处的某些解决方案不能防止发生后退事件-他们使后退事件发生(并且浏览器内存中有关页面的数据丢失),然后它们播放前向事件以尝试隐藏事实后面的事件刚刚发生。如果页面保持瞬态状态,则不会成功。

我根据vrfvr的回答为React(当不使用react路由器时)编写了这个解决方案。

除非用户确认弹出窗口,否则它将真正阻止后退按钮执行任何操作:

  const onHashChange = useCallback(() => {
    const confirm = window.confirm(
      'Warning - going back will cause you to loose unsaved data. Really go back?',
    );
    window.removeEventListener('hashchange', onHashChange);
    if (confirm) {
      setTimeout(() => {
        window.history.go(-1);
      }, 1);
    } else {
      window.location.hash = 'no-back';
      setTimeout(() => {
        window.addEventListener('hashchange', onHashChange);
      }, 1);
    }
  }, []);

  useEffect(() => {
    window.location.hash = 'no-back';
    setTimeout(() => {
      window.addEventListener('hashchange', onHashChange);
    }, 1);
    return () => {
      window.removeEventListener('hashchange', onHashChange);
    };
  }, []);

答案 28 :(得分:0)

只需设置location.hash="Something"。按下后退按钮后,哈希将从网址中删除,但页面不会返回。

此方法有助于防止意外返回,但是出于安全目的,您应设计后端以防止重新应答。

答案 29 :(得分:0)

你根本不能也不应该这样做。但是,这可能会有所帮助

<script type = "text/javascript" >
history.pushState(null, null, 'pagename');
window.addEventListener('popstate', function(event) {
history.pushState(null, null, 'pagename');
});
</script>

适用于我的chrome和firefox

答案 30 :(得分:0)

您可以放一个小的脚本,然后检查。它不允许您访问上一页。 这是用javascript完成的。​​

<script type="text/javascript">
    function preventbackbutton() { window.history.forward(); }
    setTimeout("preventbackbutton()", 0);
    window.onunload = function () { null };
</script>

当您尝试通过浏览器访问上一页或上一页时,会触发window.onunload功能。

希望这会有所帮助。

答案 31 :(得分:0)

我创建了一个HTML页面(index.html)。我还在(脚本)文件夹/目录中创建了一个(mechanism.js)。然后,我根据需要使用form,table,span和div标签将所有内容放在(index.html)中。现在,这是让后退/前锋无所作为的伎俩!

首先,你只有一页!其次,使用带有span / div标签的JavaScript可以在需要时通过常规链接隐藏和显示同一页面上的内容!

在'index.html'中:

    <td width="89px" align="right" valign="top" style="letter-spacing:1px;">
     <small>
      <b>
       <a href="#" class="traff" onClick="DisplayInTrafficTable();">IN</a>&nbsp;
      </b>
     </small>
     [&nbsp;<span id="inCountSPN">0</span>&nbsp;]
    </td>

内部'mechanism.js':

    function DisplayInTrafficTable()
    {
     var itmsCNT = 0;
     var dsplyIn = "";
     for ( i=0; i<inTraffic.length; i++ )
     {
      dsplyIn += "<tr><td width='11'></td><td align='right'>" + (++itmsCNT) + "</td><td width='11'></td><td><b>" + inTraffic[i] + "</b></td><td width='11'></td><td>" + entryTimeArray[i] + "</td><td width='11'></td><td>" + entryDateArray[i] + "</td><td width='11'></td></tr>";
     }
     document.getElementById('inOutSPN').innerHTML = "" +
                                             "<table border='0' style='background:#fff;'><tr><th colspan='21' style='background:#feb;padding:11px;'><h3 style='margin-bottom:-1px;'>INCOMING TRAFFIC REPORT</h3>" + DateStamp() + "&nbsp;&nbsp;-&nbsp;&nbsp;<small><a href='#' style='letter-spacing:1px;' onclick='OpenPrintableIn();'>PRINT</a></small></th></tr><tr style='background:#eee;'><td></td><td><b>###</b></td><td></td><td><b>ID #</b></td><td></td><td width='79'><b>TYPE</b></td><td></td><td><b>FIRST</b></td><td></td><td><b>LAST</b></td><td></td><td><b>PLATE #</b></td><td></td><td><b>COMPANY</b></td><td></td><td><b>TIME</b></td><td></td><td><b>DATE</b></td><td></td><td><b>IN / OUT</b></td><td></td></tr>" + dsplyIn.toUpperCase() + "</table>" +
                                             "";
     return document.getElementById('inOutSPN').innerHTML;
    }

它看起来很毛茸茸,但请注意函数名称和调用,嵌入式HTML和span标记id调用。这是为了说明如何在同一页面上将不同的HTML注入相同的span标签!后退/前进如何影响此设计?它不能,因为你隐藏了对象并在同一页面上替换了所有对象!

如何隐藏和显示?开始: 根据需要在'mechanism.js'中的内部函数,使用:

    document.getElementById('textOverPic').style.display = "none"; //hide
    document.getElementById('textOverPic').style.display = "";     //display

在'index.html'内部通过链接调用函数:

    <img src="images/someimage.jpg" alt="" />
    <span class="textOverPic" id="textOverPic"></span>

    <a href="#" style="color:#119;font-size:11px;text-decoration:none;letter-spacing:1px;" onclick="HiddenTextsManager(1);">Introduction</a>

我希望我没有让你头痛。对不起,如果我这样做了: - )

答案 32 :(得分:0)

在我的情况下,这是一个购物订单。所以我做的是禁用按钮。当用户单击后,该按钮仍被禁用。当他们再次点击后退,然后点击页面按钮继续前进。我知道他们的订单已经提交并跳到另一页。

当页面实际刷新时,按钮(理论上)可用;然后,我能够在页面加载中对订单已经提交作出反应,然后重定向。

答案 33 :(得分:-1)

//"use strict";
function stopBackSpace(e) {
    var ev = e || window.event;
    var obj = ev.target || ev.srcElement;
    var t = obj.type || obj.getAttribute('type');

    var vReadOnly = obj.getAttribute('readonly');
    var vEnabled = obj.getAttribute('enabled');
    // null
    vReadOnly = (vReadOnly == null) ? false : vReadOnly;
    vEnabled = (vEnabled == null) ? true : vEnabled;
    // when click Backspace,judge the type of obj.

    var flag1 = ((t == 'password' || t == 'text' || t == 'textarea') && ((vReadOnly == true || vReadOnly == 'readonly') || vEnabled != true)) ? true : false;

    var flag2 = (t != 'password' && t != 'text' && t != 'textarea') ? true : false;

    if (flag2) {
        e.keyCode = 0;
        e.cancelBubble = true;
        return false;
    }
    if (flag1) {
        e.keyCode = 0;
        e.cancelBubble = true;
        return false;
    }
}
if (typeof($) == 'function') {
    $(function() {
        $(document).keydown(function(e) {
            if (e.keyCode == 8) {
                return stopBackSpace(e);
            }
        });
    });
} else {
    document.onkeydown = stopBackSpace;
}

答案 34 :(得分:-2)

这是另一种进行方法。我们可以添加简短的SessionStorage条件,而不仅仅是避免避免使用“后退”按钮功能(该功能无法可靠地工作)。

假设我们有三个不同的页面(page1,page2和page3)。在每个页面上,我们都有单击链接的链接以进入下一个页面,我们不希望用户能够返回到上一页。

在第一页(page1.html)上,我们创建一个带有虚拟“ prev”代码的SI(sessionStorage Item),另一个创建一个带有“ page1”代码(SI“ now”)的SI:

  PAGE 1  <button onclick="goto()">PAGE 2</button>

  -------------------

  let thispage = '1' // Or 123456 if preferred or make sense

  // You can replace this fixed 'thispage' value on each page with a script counting the clicks
  // or any other way to increase its value, i.e., thispage++
  // or what you want, even counting the url.length (lol)

  sessionStorage.setItem('prev', '0') // Dummy code
  sessionStorage.setItem('now', thispage)

  // You can here make this page unreachable with page2/page3 SI same conditions

  function goto(){
      window.location = "page2.html"
  }

在page2.html上,我们使用常规的NoBack脚本(如果可行),并且仅当我们来自page1时才更新SI:

  PAGE 2  <button onclick="goto()">PAGE 3</button>

  -------------------

  // If it works, let it work :-)

  history.pushState(null, null, location.href);
  history.back();
  history.forward();
  window.onpopstate = function () {
      history.go(1);
  };

  // else

  let thispage = '2' // 456789
  let thisprev = sessionStorage.getItem('now')
  if(sessionStorage.getItem('prev')==thispage) {
      console.log('USER is back on PAGE 2')
      setTimeout(function() { goto() }, 1000); // Remove log + setTimeout
  }
  if(thisprev !== thispage) {
      if(thisprev < thispage) {
          console.log('USER is coming from PAGE 1')
          sessionStorage.setItem('prev', thisprev)
          sessionStorage.setItem('now', thispage)
      }
      else {
          console.log('USER try to reload this page')
          setTimeout(function() { goto() }, 1000);
      }
  }

  function goto(){
      window.location = "page3.html"
  }

在page3.html上:

  PAGE 3  <button onclick="goto()">BACK TO PAGE 1</button>

  -------------------

  history.pushState(null, null, location.href);
  history.back();
  history.forward();
  window.onpopstate = function () {
      history.go(1);
  };

  let thispage = '3' // 999999
  let thisprev = sessionStorage.getItem('now')
  if(sessionStorage.getItem('prev') == thispage) {
      goto()
  }
  if(thisprev !== thispage) {
      if(thisprev < thispage) {
          sessionStorage.setItem('prev', thisprev)
          sessionStorage.setItem('now', thispage)
      }
      else {
          goto()
      }
  }
  function goto(){
      window.location = "page1.html" // Reinit test
  }

优点是,即使用户手动重新加载上一页(如果他有时间查看并记住该URL),它仍然可以工作。尚未在所有设备上进行测试,但是似乎可以在Firefox + Chrome + Edge Windows 10和OS X上的Firefox + Chrome上正常运行。