【问题标题】:Disable browser's back button禁用浏览器的后退按钮
【发布时间】:2010-10-31 23:07:47
【问题描述】:

如何禁用浏览器的返回按钮(跨浏览器)?

【问题讨论】:

  • 您不拥有用户的计算机或浏览器。
  • +1 因为虽然我同意禁用浏览器后退按钮是“不好的做法”,但我认为没有理由对问题本身投反对票,回答并解释为什么要走 imo。
  • 为什么我们对这个问题怀有敌意?据我们所知,提出这个问题的人已经知道这是一种糟糕的可用性实践,但只是遵循要求,或者他们只是想学习一些东西。为什么我们不假装这是一个假设性问题,并回答如果我们要做那种事情我们会怎么做?
  • 有些事情永远不应该做,不管有没有想做的事情。对此有不可协商的要求立即表示要求是由没有业务设置的人设置的,这是一个更大的问题。
  • 呃,我撰写了有史以来最棒的评论,但是当我不小心按了后退按钮时,它丢失了。

标签: asp.net javascript


【解决方案1】:

不要禁用预期的浏览器行为。

让您的页面处理用户返回一两个页面的可能性;不要试图削弱他们的软件。

【讨论】:

  • 谢谢老兄,问题是如果你正在构建一个 AJAX 应用程序,在禁用后退按钮或浏览你的应用程序并为每个和制定适当的后退操作之间进行成本效益权衡在每种可能的情况下,都可能倾向于禁用后退按钮,这是两者中更具吸引力的选项。
  • 我同意乔纳森的观点,尤其是在互联网上充斥着大量重定向恶意软件广告的情况下,他们已经滥用警报系统,让他们的页面难以离开,而没有让他们真正锁定你的能力在他们的页面上
  • “禁用”后退按钮是一个非常常见的用例:对于任何需要身份验证/安全性的应用程序,您不希望用户能够按下后退按钮并查看其他人看到的页面已登录的用户。您将在任何需要登录的 Web 应用程序中看到此行为,例如 ameritrade.com。不幸的是,stackoverflow.com 在这方面并不铁定。如果您注销并开始点击返回按钮,注销的前几页似乎受到保护,但您将能够查看登录用户访问的内容:(
【解决方案2】:

我想出了一个小技巧,可以使用 JavaScript 禁用后退按钮。我在 chrome 10、firefox 3.6 和 IE9 上检查过:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<title>Untitled Page</title>
<script type = "text/javascript" >
function changeHashOnLoad() {
     window.location.href += "#";
     setTimeout("changeHashAgain()", "50"); 
}

function changeHashAgain() {
  window.location.href += "1";
}

var storedHash = window.location.hash;
window.setInterval(function () {
    if (window.location.hash != storedHash) {
         window.location.hash = storedHash;
    }
}, 50);


</script>
</head>
<body onload="changeHashOnLoad(); ">
Try to hit the back button!
</body>
</html>

它在做什么?

来自评论:

此脚本利用了这样一个事实,即浏览器将 URL 中“#”号之后的任何内容视为浏览历史记录的一部分。它的作用是:当页面加载时,“#1”被添加到 URL。 50ms 后,“1”被删除。当用户单击“返回”时,浏览器会将 URL 更改回删除“1”之前的状态,但是 - 它是同一个网页,因此浏览器不需要重新加载页面。 – Yossi Shasho

【讨论】:

  • 看起来这个脚本在页面加载时会在 URL 中添加“#”,并且每 50ms 会在 URL 上附加一个 1。
  • 该脚本利用了这样一个事实,即浏览器将 URL 中“#”符号之后的内容视为浏览历史记录的一部分。它的作用是:当页面加载时,“#1”被添加到 URL。 50ms 后,“1”被删除。当用户单击“返回”时,浏览器会将 URL 更改回删除“1”之前的状态,但是 - 它是同一个网页,因此浏览器不需要重新加载页面。
  • 请注意,URL 更改了两次:我们这样做只是为了掩饰实现,所以没有人会看到我们添加了“1”。所以实际上当用户点击返回时,页面会重新添加“#1”,然后再次将其删除。顺便说一句 - 它不必是“1”,它可以是任何字符串。
  • 这个问题是页面每 50 毫秒滚动到顶部。如果您的表单大于窗口高度,这将导致无法填写表单值。
  • 非常感谢。这对于我拥有的基于 JavaScript 的特别交互式页面非常有用,其中左右滚动是机制的一部分。这有助于消除 Mac OS X 上滚动手势导致用户意外“返回”页面的问题(如果他们已经一直滚动,这一切都很容易做到)。
【解决方案3】:

其他人采取的方法是说“不要这样做”,但这并不能真正回答发帖人的问题。让我们假设每个人都知道这是一个坏主意,但我们很好奇它是如何完成的......

您不能禁用用户浏览器上的后退按钮,但您可以禁用该按钮,以便在用户返回时您的应用程序中断(显示错误消息,要求用户重新开始)。

我见过的一种方法是在应用程序和每个表单中的每个 URL 上传递一个令牌。令牌会在每个页面上重新生成,一旦用户加载新页面,之前页面中的任何令牌都会失效。

当用户加载页面时,该页面仅在正确的令牌(已提供给前一页面上的所有链接/表单)被传递给它时才会显示。

我的银行提供的网上银行应用程序是这样的。如果您完全使用后退按钮,则无法再使用任何链接,也无法重新加载页面 - 相反,您会看到一条通知,告诉您无法返回,您必须重新开始。

【讨论】:

  • 我的银行采用了不同的方法——它完全终止了会话。使用后退按钮相当于退出。
  • 这听起来像是同样的方法。他们检测到您已经返回并引发了错误情况。
  • joomla 也解决了令牌解决方案,每个页面和每个表单都会生成一个令牌,实际上这种做法存在一些问题,例如“当用户在页面上停留过多时,他的令牌过期”
  • 不要误会我的意思,这种做法有很多问题。我不是推荐它,我只是说它通常是如何实现的。它们在页面之间传递唯一标记,以检测您没有关注上一页中的预期链接之一,然后终止会话或显示错误。它破坏了后退按钮,破坏了选项卡式浏览,破坏了书签和/或共享链接等等 - 而且,它并没有真正解决任何问题。
  • 如果问题是如果用户尝试使用后退按钮导致信息丢失或中断,那么禁用后退按钮将是一种更理想的方法。
【解决方案4】:

这个问题和这个one...很相似

您需要强制缓存过期才能使其正常工作。将以下代码放在你的页面代码后面。

Page.Response.Cache.SetCacheability(HttpCacheability.NoCache)

【讨论】:

  • 请注意,使页面不可缓存并不能实现 OP 想要的:使用后退按钮禁用访问页面。即使浏览器在使用后退按钮时遵守无缓存(哪些浏览器没有义务执行 AFAIK),它们仍然提供重新加载该页面的方法(通常在显示警告对话框之后)。因此,如果您真的不希望您的用户返回该页面,情况可能会更糟,因为对该页面的请求必须一直到达源服务器。您将需要一些服务器端的东西来检测页面已被重新访问。标题可以忽略。
  • 禁用后退按钮是一个非常常见的用例:对于任何需要身份验证/安全性的应用程序,您不希望用户能够按下后退按钮并查看其他用户看到的页面已登录。您将在任何需要登录的 Web 应用程序中看到此行为,例如 ameritrade.com。不幸的是,stackoverflow.com 在这方面并不铁定。如果您注销并开始点击返回按钮,注销的前几页似乎受到保护,但您将能够查看登录用户访问的内容:(
【解决方案5】:

当我自己在寻找答案时, “最佳实践”已经……过时了……就像浏览器一样。(浏览器真的是丑陋的化石)

最好/最安全的解决方案是让浏览器实现一种方法/请求,用户可以在其中授予页面控制界面的能力。

为什么?因为对于我当前的项目,我正在构建一个 100% JavaScript 构建和控制的界面。并且后退按钮在我的项目中没有位置,因为没有页面更改。 (即非常快,并且因为刷新而没有页面闪烁......就像一个真正的应用程序!)

我知道为什么没有“劫持”界面的能力,我理解。但至少我们应该能够从浏览器请求它!现在这确实是没有劫持危险的“最佳实践”。

但是浏览器就是浏览器。我不希望在这方面发生任何事情。

【讨论】:

  • 100% 不同意,虽然这个功能对 99% 的 web 开发者来说是很棒的,剩下的 1% 会滥用这个功能,让网站控制你的能力太危险了要使用互联网,在我看来,跨域重定向脚本需要禁止或允许确认是否允许运行脚本,因为只是这种滥用
  • @MikeT - 在我自己的特定应用程序页面上导航时禁用“后退”按钮会如何抑制任何人使用 Internet 的能力?
  • @PoloHoleSet 如果您能够禁用浏览器的后退按钮,那么每个人都可以,您所需要的只是一个重定向将您发送到您不想访问的页面,如果他们可以禁用浏览器中的导航控件你如何逃脱?我确定您已经遇到过“您有病毒页面”,他们会提示您安装病毒以删除不存在的病毒,现在想象一下他们实际上可以阻止您离开的站点
  • @MikeT - 我可以在导航窗口中输入任何其他 url,我可以关闭一个选项卡,我可以禁用 javascript。关键不在于是否有人可以,因为你可以,我可以,任何人都可以。作为一个政策问题,人们说你不应该,如果可以的话。我们不是在讨论如何设计浏览器,而是在讨论如何对应用程序进行编程。
  • @PoloHoleSet 如果您要锁定导航,您需要锁定的不仅仅是后退按钮,因为浏览器历史记录和键入的 url 也会为用户提供绕过您的工作流程的方法。就像我说的那样,我们不是在谈论你或我会做什么,而是恶意元素,如果防止恶意网站控制你的浏览器的唯一方法是禁用浏览器上的所有 js,那么你已经破坏了互联网现代网络依赖脚本来提供内容,这是我的观点,如果您想对用户进行如此多的控制,请创建一个应用程序来为您的工作流程提供服务
【解决方案6】:

我正在搜索相同的问题,并在网站上找到了以下代码。想在这里分享一下:

function noBack()
{
   window.history.forward()
}
noBack();
window.onload = noBack;
window.onpageshow = function(evt){ if(evt.persisted) noBack(); }
window.onunload = function(){ void(0); }

然而,正如上述用户所指出的,这绝不是一个好的做法,出于各种原因应该避免这样做。

【讨论】:

  • 最好能说明应该避免的原因。
  • 据我了解,从技术上讲,您无法禁用某人浏览器上的“后退”按钮,您只能使该按钮不可用或继续加载同一页面。与其通过 JS 来做,不如使用服务器端代码并​​使用不需要使用后退按钮的正确逻辑。应使用其他操作,例如重新加载同一页面或显示自定义消息。
【解决方案7】:

如果您依赖客户端技术,则可以绕过它。例如,Javascript 可能会被禁用。或者用户可能会执行一个 JS 脚本来解决您的限制。

我的猜测是您只能通过服务器端跟踪用户会话并将用户/浏览器重定向(如在 Server.Transfer,而不是 Response.Redirect)到所需页面来做到这一点。

【讨论】:

    【解决方案8】:
    <body onLoad="if(history.length>0)history.go(+1)">
    

    【讨论】:

      【解决方案9】:

      有几种不同的实现。 IE 有一个 flash 解决方案和一些 iframe/frame 解决方案。看看这个

      http://www.contentwithstyle.co.uk/content/fixing-the-back-button-and-enabling-bookmarking-for-ajax-apps

      顺便说一句:禁用(或至少阻止前一步)后退按钮有很多正当理由 - 以 gmail 为例,它实现了上述文章中讨论的哈希解决方案。

      谷歌“ajax 如何破坏后退按钮”,您会发现大量关于用户测试和禁用后退按钮有效性的文章。

      【讨论】:

      • 还可以查看 Facebook 的新照片查看器。请注意,后退按钮会将您带回照片(这是您想要的),而不是浏览器默认设置
      【解决方案10】:

      我也有同样的问题,在 head 标签或 in 上使用这个 Java 脚本函数,它 100% 工作正常,不会让你回去。

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

      【讨论】:

        【解决方案11】:

        试试这个代码。为我工作。它基本上会在页面加载后立即更改哈希,通过在 URL 上添加“1”来更改最近的历史记录页面。因此,当您点击返回按钮时,它每次都会重定向到同一页面。

         <script type="text/javascript">
            var storedHash = window.location.hash;
            function changeHashOnLoad() { window.location.hash = "1";}
            window.onhashchange = function () {
                window.location.hash = storedHash;
            }
        </script>
        
        <body onload="changeHashOnLoad(); ">
        
        </bod>
        

        【讨论】:

          【解决方案12】:

          您应该使用具有适当过期和缓存标头的帖子。

          【讨论】:

          • 查看我对 this answer 的评论,了解为什么这不起作用。
          【解决方案13】:

          与其尝试禁用浏览器后退按钮,不如支持它。 .NET 3.5 可以很好地处理浏览器的后退(和前进)按钮。用 Google 搜索:“Scriptmanager EnableHistory”。 您可以控制哪些用户操作会将条目添加到浏览器的历史记录(ScriptManager -> AddHistoryPoint),并且只要用户单击浏览器的后退/前进按钮,您的 ASP.NET 应用程序就会收到一个事件。 这适用于所有已知的浏览器

          【讨论】:

            【解决方案14】:

            在全球范围内,禁用后退按钮确实是不好的做法。但是,在某些情况下,后退按钮功能没有意义。

            这是防止页面之间不必要的导航的一种方法:

            首页(文件top.php):

            <?php
                session_start();
                $_SESSION[pid]++;
                echo "top page $_SESSION[pid]";
                echo "<BR><a href='secondary.php?pid=$_SESSION[pid]'>secondary page</a>";
            ?>
            

            次要页面(文件secondary.php):

            <?php
                session_start();
                if ($_SESSION[pid] != $_GET[pid]) 
                    header("location: top.php");
                else {
                    echo "secondary page $_SESSION[pid]";
                    echo "<BR><a href='top.php'>top</a>";
                }
            ?>
            

            效果是允许使用您自己的链接从首页向前导航到次要页面并返回(例如取消)。但是,在返回首页后,浏览器后退按钮无法导航到二级页面。

            【讨论】:

              【解决方案15】:

              即使我以前也遇到过同样的情况……但没有任何帮助。 试试这些东西,也许这些对你有用

              在登录页面&lt;head&gt;标签:

              <script type="text/javascript">
                  window.history.forward();
              </script>
              

              在注销按钮中我这样做了:

              protected void Btn_Logout_Click(object sender, EventArgs e)      
              {
                  connObj.Close();
                  Session.Abandon();
                  Session.RemoveAll();
                  Session.Clear();
                  HttpContext.Current.Session.Abandon();
              }
              

              在登录页面上,我将焦点放在用户名文本框上,如下所示:

              protected void Page_Load(object sender, EventArgs e)
              {
                  _txtUsername.Focus();
              }
              

              希望这会有所帮助... :) 有人请教我如何编辑此页面...

              【讨论】:

              • a) 编辑您的答案 b) 单击问号 c) 单击高级帮助 d) 阅读并应用 :-) 另请注意,ctrl-k 取消/缩进所选块以取消/格式化作为代码。再加上格式化程序不能很好地处理制表符(不过在这里可能不是问题)
              【解决方案16】:

              如果您需要在 Web 应用程序中轻柔地抑制删除键和退格键,以便在它们编辑/删除项目时页面不会被意外重定向,您可以使用以下代码:

              window.addEventListener('keydown', function(e) {
                var key = e.keyCode || e.which;
                if (key == 8 /*BACKSPACE*/ || key == 46/*DELETE*/) {
                  var len=window.location.href.length;
                  if(window.location.href[len-1]!='#') window.location.href += "#";
                }
              },false);
              

              【讨论】:

                【解决方案17】:

                试试这个代码。 您只需要在母版页中实现此代码,它就会在所有页面上为您工作

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

                【讨论】:

                  【解决方案18】:

                  Yossi Shasho's Code 的问题是页面每 50 毫秒滚动到顶部。所以我修改了那个代码。现在它在所有现代浏览器、IE8 及更高版本上都能正常工作

                  var storedHash = window.location.hash;
                  function changeHashOnLoad() {
                      window.location.href += "#";
                      setTimeout("changeHashAgain()", "50");
                  }
                  
                  function changeHashAgain() {
                      window.location.href += "1";
                  }
                  
                  function restoreHash() {
                      if (window.location.hash != storedHash) {
                          window.location.hash = storedHash;
                      }
                  }
                  
                  if (window.addEventListener) {
                      window.addEventListener("hashchange", function () {
                          restoreHash();
                      }, false);
                  }
                  else if (window.attachEvent) {
                      window.attachEvent("onhashchange", function () {
                          restoreHash();
                      });
                  }
                  $(window).load(function () { changeHashOnLoad(); });
                  

                  【讨论】:

                    【解决方案19】:

                    这似乎对我们有用。

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

                    【讨论】:

                      【解决方案20】:
                      <script>
                          $(document).ready(function() {
                              function disableBack() { window.history.forward() }
                      
                              window.onload = disableBack();
                              window.onpageshow = function(evt) { if (evt.persisted) disableBack() }
                          });
                      </script>
                      

                      【讨论】:

                        猜你喜欢
                        • 2011-08-06
                        • 2014-04-17
                        • 1970-01-01
                        • 2011-04-06
                        • 2020-05-15
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多