如何控制与浏览器后退按钮一起使用的网站页面访问

How*_*arr 5 javascript browser-history

我在“ head”部分和sessionStorage变量中使用Java脚本来控制网页的查看;以确保执行正确的登录和前提事件。在此示例中,我将使用3页,默认,登录和菜单页。

目的是防止通过地址栏直接访问“登录”和“菜单”页面,而无需先访问“默认”页面。

默认页面具有以下条件:

  <head>
    <script>
      <!-- Page Access Check -->
      sessionStorage.Page="Default";
      if(sessionStorage.MemberData){
        sessionStorage.Page="Menu";
        location.assign("Menu.asp");
      }
    </script>
  </head>
Run Code Online (Sandbox Code Playgroud)

默认页面是网站的访问点,所有用户都必须在此输入。sessionStoreage.Page变量指示允许显示的页面。在后续的代码示例中,此变量的目的将变得更加明显。

如果当前用户已经成功登录,因此不需要再次登录,则将设置sessionStorage.MemberData。因此,将sessionStorage.Page变量设置为“ Menu”,并将用户定向到Menu页面。

  <body>
    <script>
      $(document).ready(function(){
        <!-- Initialize Event Handlers -->
        $("#LoginButton").one("click",function(){
          sessionStorage.Page="Login";
          location.assign("Login.asp");
        });
      });
    </script>
  </body>
Run Code Online (Sandbox Code Playgroud)

“默认”页面具有一个链接到“登录”页面的按钮,成功登录后,会将用户带到“菜单”页面。“登录”按钮将sessionStorage.Page变量设置为“登录”,并将用户定向到“登录”页面。

  <head>
    <script>
      <!-- Page Access Check -->
      switch(sessionStorage.Page){
        case "Login":                   // Page Allowed
          break;
        default:
          history.back();
      }
    </script>
  </script>
Run Code Online (Sandbox Code Playgroud)

到达“登录”页面后,将检查sessionStorage.Page变量,如果该值设置为“登录”,则将授予对该页面的访问权限。否则,用户将被引导回到他们来自的页面,即先前所在页面的“默认”页面。

    sessionStorage.MemberData=JSON.stringify(MemberData);
    sessionStorage.Page="Menu";
    location.assign("Menu.asp");
Run Code Online (Sandbox Code Playgroud)

成功登录后,将设置sessionStorage.MemberData(请参阅“默认”页面中的检查),将sessionStorage.Page变量设置为“ Menu”,并将用户定向到Menu页面。

  <head>
    <script>
      <!-- Page Access Check -->
      switch(sessionStorage.Page){
        case "Menu":                     // Page Allowed
          break;
        default:
          history.back();
      }
    </script>
Run Code Online (Sandbox Code Playgroud)

到达“菜单”页面后,将检查sessionStorage.Page变量,如果该值设置为“菜单”,则授予对该页面的访问权限。否则,用户将被引导回到他们来自的页面,在大多数情况下是“登录”页面。

    <script>
      $("#LogoutButton").one("click",Logout)

      function Logout(){
        sessionStorage.removeItem("MemberData");
        history.back();
      }
    </script>
Run Code Online (Sandbox Code Playgroud)

“菜单”页面上有一个“注销”按钮,可删除sessionStorage.MemberData变量并使用户返回到上一页“登录页面”。

由于sessionStorage.Page值仍设置为“ Menu”,因此Login页面的Page Access Check将用户转到其上一个页面Default。

这些页面需要使用浏览器的后退按钮才能很好地播放。

  <head>
    <script>
      <!-- Page Access Check -->
      switch(sessionStorage.Page){
        case "Menu":                    // Page Allowed
          break;
        case "Admin":                   // Back From
          sessionStorage.Page="Menu";
          break;
        default:
          history.back();
      }
    </script>
  </head>
Run Code Online (Sandbox Code Playgroud)

在此示例中,用户可以使用“后退”按钮从“管理”页面导航回到“菜单”页面。在这种情况下,sessionStorage.Page变量仍设置为“ Admin”,并且检查将失败。随后的检查允许从Admin成功返回。

现在,话虽如此,这就是问题所在:浏览器历史记录堆栈未按预期工作。

从新的浏览器选项卡中,我导航到“默认”页面。查看历史记录堆栈,我可以看到“ New Tab”在上一页的位置,而没有下一页。

*Default
 New Tab
Run Code Online (Sandbox Code Playgroud)

单击“默认”页面上的“登录”按钮会将我带到“登录”页面。现在,历史记录堆栈在上一页中显示“默认”和“新选项卡”,而在下一页中则没有。

*Login
 Default
 New Tab
Run Code Online (Sandbox Code Playgroud)

单击后退按钮可将我返回到“默认”页面。现在,历史记录堆栈在上一页显示“新建选项卡”,在下一页显示“登录”。

 Login
*Default
 New Tab
Run Code Online (Sandbox Code Playgroud)

单击前进按钮前进到“登录”页面,使我返回到“默认”页面。这是因为sessionStorage.Page变量仍设置为“默认”。历史记录堆栈保持不变。

成功登录并进入“菜单”页面后,历史记录堆栈现在显示“登录”,“默认”和“新建选项卡”。没有下一页。

*Menu
 Login
 Default
 New Tab
Run Code Online (Sandbox Code Playgroud)

到目前为止,所有人都按预期工作。

在菜单页面上,单击后退按钮。我所看到的是我所期望的:我被发送回Login页面,并且因为sessionStorage.Page变量仍设置为Menu,Login页面将我发送回Default页面。因为存在sessionStorage.MemberData变量,所以将我发送到“菜单”页面。

因此,这是我期望历史记录堆栈包含的内容:

             Back         Back        Assign

*Menu        Menu        Menu       *Menu
 Login      *Login       Login       Default
 Default     Default    *Default     New Tab
 New Tab     New Tab     New Tab
Run Code Online (Sandbox Code Playgroud)

但是,这是历史记录堆栈的实际情况。

 Menu
 Login
*Menu
 New Tab
Run Code Online (Sandbox Code Playgroud)

在“默认”页面的页面访问检查(该页面将我们发送到“菜单”页面)中,似乎执行了“ location.replace”而不是“ location.assign”。

单击菜单页面上的注销按钮会将我带到“新选项卡”,而不是“默认”页面,这破坏了我的页面导航。

历史记录堆栈是后进先出堆栈。当您在页面之间导航时,上一页地址将被放置在堆栈中。返回时,页面将按照“后进先出”的顺序重新加载。

通常,对于LIFO堆栈,每次返回时,都应从堆栈中删除该条目。但这会阻止您使用“前进”按钮返回到原始页面。而且,只要堆栈中的所有条目均未更改,您就可以随意在历史记录堆栈中上下移动。

但是,如果修改条目,则该点的所有条目Forward都将变为无效,并且由于尚未从该新页面建立“ Forward”路径而应将其删除。并且由于已分配了修改的条目,因此应将其放置在当前页面的顶部,而不是替换它,并且应该删除其上方的所有其他条目。

更新:

该问题可能源于时间问题。问题是“何时将地址放置在“历史记录”堆栈上?”

与jQuery一样,某些代码仅在页面准备就绪后才能执行。也许是因为在页眉处理过程中页面被重定向,所以在文档准备好之前,更新历史记录堆栈的代码没有机会执行。

关于这一点有什么想法吗?

更新2:

我试图将页面访问代码从HEAD移到jQuery内部

$(document).ready(function(){...});

希望这将延迟location.assign()到页面完全加载之后,从而可以正确更新历史记录。那没有解决问题。

location.assign("Menu.asp")仍然替换堆栈中的Default.asp的条目。此外,我已经注意到,正向条目不会从堆栈中删除,因为我相信只要改变堆栈就应该删除。

 Menu   <- Not Removed
 Login  <- Not Removed
*Menu
 New Tab
Run Code Online (Sandbox Code Playgroud)

也许有人有其他可行的方法?

德克萨斯州霍华德·帕尔·卡多·米尔斯

mZe*_*Zed 1

在我看来,意外的行为似乎是由history.back()和location.assign()的组合引起的,当您浏览历史堆栈并在那里分配一个新站点时,这就像您将在中创建一个新条目一样历史的时间线。

如果是这种情况,我宁愿期望历史堆栈看起来像这样:

     Menu
     Login
     *Menu
     Default
     New Tab
Run Code Online (Sandbox Code Playgroud)

默认值自动分配给history.back(),因此它就像这里的一个看不见的步骤 - 它实际上在那里,但当您返回到菜单时,总是会到达菜单。