【问题标题】:Prevent back button防止返回按钮
【发布时间】:2023-04-02 22:26:01
【问题描述】:

我在带有 C# 的 ASP.NET MVC 上使用 Razor。

我正在调用外部网页来处理信用卡,它会返回给我。然后我显示收据。

我想阻止他们返回上一个屏幕。

我没有像 asp 这样的底层 cs 页面,因为这些是 .cshtml 文件来获取事件。

这个收据页面是一个视图,所以我不能将 JavaScript 放在标题中,因为它会影响使用它的每个页面。

有人知道在这种情况下我如何防止返回按钮吗?

【问题讨论】:

  • 这将是一段 javascript 代码来执行此操作。 C# 与它没有任何关系,因为 C# 都是服务器端的。不过,我相信你可以在 Stackoverflow 上搜索答案。 Edit: I did the search for you.
  • 此外,如果您在 Razor 文件中使用部分,则可以从特定的局部视图 Razor 文件在页面中注入 javascript。查看此博客了解更多信息:weblogs.asp.net/scottgu/archive/2010/12/30/…
  • 不能在浏览器上禁用脚本,从而忽略这一点吗?
  • 是的。无论如何,您仍然必须编写代码以确保人们不会搞砸事情。或者如果 js 被禁用,就阻止用户使用该站点。不过,该决定取决于网站的功能、您的用户群等。

标签: c# asp.net-mvc razor back-button


【解决方案1】:

一种可能性是从客户端缓存中排除您不想返回的页面。这可以通过设置正确的响应标头来完成。这是一个带有 [NoCache] 自定义操作过滤器的示例,您可以使用它来装饰相应的控制器操作。

【讨论】:

  • 完美!!非常感谢!
【解决方案2】:

首先,如果之前的页面已经向服务器投递了数据,最好在处理成功后Redirect(...)到另一个action,避免“刷新”时重新提交数据。

然后也将页面设置为过期,这样后退按钮就不起作用了:

https://stackoverflow.com/a/5352953/864763

【讨论】:

    【解决方案3】:

    你问错问题了。不要尝试在客户端禁用“返回”。这注定会失败;你也许可以让它变得更难,但你永远不会赢得那场战斗。相反,您应该重新编写您拥有的特定页面,以便它只会处理信用卡一次。你应该(在服务器上)“记住”你已经处理了信用卡,这样如果用户返回页面重新提交它,你可以给他们一个错误消息,说“你已经提交了这个信息,你不能提交此请求两次”。

    现在,有几种方法可以实现这个总体目标,有些方法比其他方法更好,但这是您需要努力实现的目标。

    一种方法是转到将用户重定向到此信用卡表单的每个页面;就在提交请求之前向该用户的会话添加一些内容(即"pendingCreditCardSubmission" = true)一旦他们提交了该请求,您就可以检查该会话变量。如果为真,则提交请求并将其设置为假,如果为假或不存在,则向用户发送错误消息。

    【讨论】:

    • 这里;对一个非常古老的答案感到不满!
    【解决方案4】:

    这就是我们的做法:

    public class NoBackFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.HttpContext.Response.ExpiresAbsolute = DateTime.Now;
            filterContext.HttpContext.Response.Expires = 0;
            filterContext.HttpContext.Response.CacheControl = "no-cache";
            filterContext.HttpContext.Response.Buffer = true;
            filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow);
            filterContext.HttpContext.Response.Cache.SetNoStore();
            filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
            if (!filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.HttpContext.Request.HttpMethod != "POST" && !filterContext.Controller.ControllerContext.IsChildAction)
            {
                var after = filterContext.HttpContext.Request.RawUrl;
                var session = GetSession(filterContext);
                if (session["Current"] != null)
                {
    
    
                    if (session["Before"] != null && session["Before"].ToString() == after)
                        filterContext.HttpContext.Response.Redirect(session["Current"].ToString());
                    else
                    {
                        session["Before"] = session["Current"];
                        session["Current"] = after;
                    }
                }
                else
                {
                    session["Current"] = after;
                }
            }
            base.OnActionExecuting(filterContext);
    
        }
    
        private HttpSessionStateBase GetSession(ActionExecutingContext context)
        {
            return context.HttpContext.Session;
        }
    
    }
    

    在此之后,您可以在通用范围或控制器范围内实现它。

    【讨论】:

      【解决方案5】:

      这个问题已经很久没有问过了,但我的解决方法是在 WebPageController 类上方添加 [NoCache]。

       [NoCache]
      public class WebPageController : Controller
      {
          public JsonResult JsonError(Exception exception)
          {
              if (exception == null) throw new ArgumentNullException("exception");
      
              Response.StatusCode = 500;
      
              return new JsonResult
              {
                  JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                  Data = new
                  {
                      error = true,
                      success = false,
                      message = exception.Message,
                      detail = exception.ToString()
                  }
              };
          }
      

      【讨论】:

        【解决方案6】:

        在MVC aspnet框架中,你可以选择RedirectToActionPermanent

        然后它告诉浏览器 301 响应代码。

        https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.redirecttoactionpermanent?view=aspnetcore-5.0

        【讨论】:

          猜你喜欢
          • 2012-05-17
          • 2012-04-18
          • 1970-01-01
          • 1970-01-01
          • 2022-01-01
          • 2012-05-07
          • 1970-01-01
          • 1970-01-01
          • 2010-10-14
          相关资源
          最近更新 更多